25行代码AC_ 2017年C/C++ A组第四题 方格分割(dfs剪痕+解题报告)

   日期:2020-10-03     浏览:114    评论:0    
核心提示:励志用少的代码做高效表达问题描述:6x6的方格,沿着格子的边线剪开成两部分。要求这两部分的形状完全相同。 如图:p1.png, p2.png, p3.png 就是可行的分割法。 试计算:包括这3种分法在内,一共有多少种不同的分割方法。注意:旋转对称的属于同一种分割法。题意分析几种分析思路:暴力列举: 直接枚举18个点,然后判断。 但时间耗费太高。 放弃。对格子dfs:dfs无法识别T型图案(因为深搜只能遍历一条路),因此放弃想了又想, 如果对边线进行dfs,从中间点出发

励志用少的代码做高效表达

问题描述:

6x6的方格,沿着格子的边线剪开成两部分。
要求这两部分的形状完全相同。

如图:p1.png, p2.png, p3.png 就是可行的分割法。

试计算:
包括这3种分法在内,一共有多少种不同的分割方法。
注意:旋转对称的属于同一种分割法。

题意分析

几种分析思路:

暴力列举: 直接枚举18个点,然后判断。 但时间耗费太高。 放弃。

对格子dfs:dfs无法识别T型图案(因为深搜只能遍历一条路),因此放弃

想了又想, 如果对边线进行dfs,从中间点出发,最后只要用深搜能到达边界, 就代表着这条线把整个图案分成了两半。 思路就出来了!

注意:图形是可以旋转的,因此最后的结果要除以4!

剪刀剪痕与dfs边界如下图所示:

代码展示:

#include<iostream>
using namespace std;
int vis[10][10];
int dire[4][2] = { -1,0, 1,0, 0,-1, 0,1};
int ans;

void dfs(int x, int y) { 
	if(x==0 || y==6 || x==6 || y==0) { 
		ans++; return;
	}
// 当前的点标注为已访问
	vis[x][y] = 1;
	vis[6-x][6-y] = 1; 
	for(int i = 0; i < 4; i++) { 
		int tx = x+dire[i][0];
		int ty = y+dire[i][1];
// 新坐标
		if(tx<0 || tx>6 || ty<0 || ty>6) continue;
		if(!vis[tx][ty]) dfs(tx, ty); 
	}
	vis[x][y] = 0;
	vis[6-x][6-y] = 0;
}

int main() { 
	vis[3][3] = 1;
	dfs(3, 3);
	cout << ans/4 << endl;
return 0; } 

感想与总结

1、蓝桥杯的绝大多数题都是搜索或暴力,而近两年纯暴力的题越来越少,取而代之的是模拟+搜索或暴力+搜索

2、本题就是一道非常标准的 模拟+搜索 类型题。 关于暴力+搜索,可参考2016年B组7题的剪邮票, 也很经典, 题目+题解,传送门

3、对于对称类型的题, 一定要考虑是否有重复的情况出现。

把手举过头顶,突然张开五指,那么,恭喜你给自己放了个烟花!

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服