25行代码AC_ 2017年C/C++ A组第四题 方格分割(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、对于对称类型的题, 一定要考虑是否有重复的情况出现。


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

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 像素格子 设计师:CSDN官方博客 返回首页