方格分割(蓝桥杯2017年试题D)

【问题描述】

6*6的方格,沿着格子的边线剪开成两部分,要求这两部分的形状完全相同。如下图所示,p1.png、p2.png、p3.png就是可行的分割法。

试计算:包括这三种分法在内,一共有多少种不同的分割方法。

注意:旋转对称的图形属于同一种分割方法。

【参考答案】

509

【解析】

这是一道典型的深度优先搜索题目。但应从何处开始搜索呢?通过观察样例图案可以发现,如果把样例图案剪开,则会有且只有两个点在边界上,且一定经过中心点(3,3)。如果以中心点(3,3)为起点进行深搜,每搜索一个点,根据对称关系,再标记其对称点,该题就可以得到解决了。

具体的注意点有以下三个。

(1)最后搜索结果

根据题意,由于旋转对称的图形属于同一种分割方法,因此最后要将得到的结果除以4,以解决四个顶点的对称性。

(2)标记对称点

当搜索一个点时,必须要有一个对称点不能被搜索,即形状的另一个部分。如果搜索点的坐标是(x,y),则根据中心对称,对称点的坐标是(6-x,6-y)。

(3)搜索方向

可以向四个方向进行搜索:向右、向左、向上、向下,这里采用方向数组 dx和dy表示。

int dx[4] = {-1,1,0,0}; int dy[4] = {0,0,-1,1}

【参考程序如下】

cpp 复制代码
#include <iostream>
using namespace std;
int dx[] = {-1,1,0,0};
int dy[] = {0,0,-1,1};
const int N = 6;
bool visited[N + 1] [N + 1];
int ans = 0;
void dfs(int x,int y)
{
	if(x == 0 || x == N || y == 0 || y == N)
	{
		ans++;
		return;
	}
	for(int i = 0; i < 4; i++)
	{
		int nx = x + dx[i];
		int ny = y + dy[i];
		if(!visited[nx][ny])
		{
			visited[nx][ny] = true;
			visited[N - nx] [N - ny] = true;
			dfs(nx,ny);
			visited[N - nx] [N - ny] = false;
			visited[nx][ny] = false;
		}
	}
}
int main(int argc, char** argv) {
	visited[N / 2] [N / 2] = true;
	dfs(N / 2,N / 2);
	cout << ans / 4;
	return 0;
}

【程序运行结果如下】

相关推荐
MERCURY.(努力写代码版)8 分钟前
leetcode--两数之和 三数之和
算法·leetcode·职场和发展
YuforiaCode1 小时前
第十五届蓝桥杯 2024 C/C++组 下一次相遇
c语言·c++·蓝桥杯
独行soc2 小时前
2025年渗透测试面试题总结-拷打题库08(题目+回答)
java·linux·运维·服务器·python·面试·职场和发展
慕容青峰4 小时前
【第十六届 蓝桥杯 省 C/Python A/Java C 登山】题解
c语言·c++·python·算法·蓝桥杯·sublime text
XiaoyaoCarter6 小时前
每日两道leetcode
c++·算法·leetcode·职场和发展·贪心算法
进击的小白菜10 小时前
二叉树层序遍历技术解析与面试指南
java·面试·职场和发展
xixihaha_dddddd13 小时前
蓝桥杯练习题2
蓝桥杯
云格~14 小时前
L1-7 矩阵列平移
开发语言·c++·算法·职场和发展·矩阵
YuforiaCode15 小时前
第十四届蓝桥杯 2023 C/C++组 日期统计
c语言·c++·蓝桥杯
_GR1 天前
2025年蓝桥杯第十六届C&C++大学B组真题及代码
c语言·数据结构·c++·算法·贪心算法·蓝桥杯·动态规划