Question:
Result: 509
Solve:
这一届的比赛简直就是搜索赛
思考:
考虑搜索的时候最容易想到的思路应该是去找连续的18个格子构成一个图案,然后去判断另一半是否与它对称,方案数是一个1~18的全排列
这个思路对于16年的《剪邮票》和13年的《剪格子》是可行的,但很明显这个方法并不能满足这道题对时间上的要求,所以得另想办法
因为题上找的是关于中心点对称的图形,那我只要以对称点为起点沿格子画出关于对称点中心对称的线,且在方格内构成两个封闭图形,就一定是一种成立的结果
eg:
实线是dfs走出的路径,虚线是dfs路径构造出的对称线,在这个思路下,只要我搜索的路径点到了
边界,就会构成两个对称的图形,然后就可以成立的状态数res++了
最后,由于题上说旋转对称的属于同一种情况,所以要res/4
Code:
#include<bits/stdc++.h>
using namespace std;
int res = 0; //结果数
//上下左右四个方向
int dir[4][2] = {0,1,0,-1,1,0,-1,0};
bool vis[7][7];
void dfs(int x, int y)
{
//状态成立,结果数加一
if(x == 0 || y == 0 || x == 6 || y == 6){
res++; return;
}
for(int i = 0; i < 4; i++)
{
int dx = x + dir[i][0];
int dy = y + dir[i][1];
判断当前点能不能走且有没有出界
if(vis[dx][dy] || x < 0 || y <0 || x > 6 || y > 6) continue;
//注意对称点也要标记
vis[dx][dy] = true; vis[6-x][6-y] = true;
dfs(dx,dy);
//回溯
vis[dx][dy] = false; vis[6-x][6-y] = false;
}
}
int main(void)
{
memset(vis,false,sizeof(vis));
dfs(3,3);
cout <<res / 4;
return 0;
}
附上蓝桥杯汇总链接:蓝桥杯C/C++A组省赛历年真题题解
声明:图片均来源于蓝桥杯官网,以个人刷题整理为目的,如若侵权,请联系删除~