您的位置:首页 > 其它

第八届蓝桥杯 方格分割

2018-03-28 20:23 465 查看
标题:方格分割

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

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

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

请提交该整数,不要填写任何多余的内容或说明文字。


 




题意:一定要注意经过旋转和对称的为一种情况;
思路一:考试的时候,我是把这个点都编号,从0~35,然后在从0~35 这36个数中选出18个(用的是top之前的不入栈,那个方法,而不是全排列),在选的时候一定要 剪枝(对称点已经在已经选过了,你在再选这个点,有意义吗),把0~35这些点转化为坐标的形式,在判断这些点是不是连通,找出所有满足的情况,再除以4,因为经过 4旋转 就又回到自己的位置了;这个旋转4次,为同一种情况;
如:下面四种为一种情况









答案:509
代码:#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

int tt[40],book[40],sum,vis[40][40],sum1;
int a[4][2] = {0,-1,1,0,0,1,-1,0};
struct node
{
int x,y;
}stu[40];
int check(int x,int y)
{
if(x>=0&&y>=0&&x<6&&y<6)
return 1;
else return 0;
}

int dfs1(int x,int y)
{
vis[x][y] = 0;
sum1++;
if(sum1==18) return 1;
for(int i =
4000
0;i<4;i++)
{
int tx = x + a[i][0];
int ty = y + a[i][1];
if(check(tx,ty)&&vis[tx][ty])
if(dfs1(tx,ty))
return 1;
}
return 0;
}
void dfs(int top,int x)
{
if(x==19)
{
int i;

memset(vis,0,sizeof(vis));
for(i=1;i<=18;i++)
{
int x = stu[tt[i]].x;
int y = stu[tt[i]].y;
vis[x][y] = 1;
}

sum1 = 0;
if(dfs1(stu[tt[1]].x,stu[tt[1]].y))
sum++;
return ;
}
for(int i = top;i<36;i++)
{
if(book[35-i]) continue;
book[i] = 1;
tt[x] = i;
dfs(i+1,x+1);
book[i] = 0;
}
}
int main()
{
memset(book,0,sizeof(book));
tt[0] = -1;
sum = 0;
for(int i = 0;i<36;i++)
{
stu[i].x = i/6;
stu[i].y = i%6;
}
dfs(0,1);
printf("sum==%d\n",sum/4);
}第一种方法太耗费时间了,但容易想;
给出的提示:1)记住 dfs 不管拐多少次弯,都是一笔画,所以不做特殊处理,普通dfs是满足不了题目要求的;2)要认真仔细审题; 
要想简单换一种思路
第二种方法,找割线,下面给出的点是,线与线的交点,不是格子的坐标;

思路:仔细观察样例数据可以发现,要满足题目所需要求,只需要剪切的线关于图案的中点中心对称。那么我们可以将格子格子之间接壤的看作边,边与边相交的看作点。则从(3,3)点出发,找一条边到达图案的外圈,不过值得注意的是,从(3,3)出发的是看错两个人出发,两个人的线路一直是对称。所以dfs中标记的时候要一步标记两个。最后的结果要除以4,因为题目中说要旋转对称的是同一种。

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int book[10][10];
int sum;
int a[4][2] = {0,-1,1,0,0,1,-1,0};
void dfs(int x,int y)
{
if(x==0||y==0||y==6||x==6)
{
sum++;
return ;
}
for(int i = 0;i<4;i++)
{
int tx = x + a[i][0];
int ty = y + a[i][1];
if(book[tx][ty]) continue;
book[tx][ty] = 1;
book[6-tx][6-ty] = 1;
dfs(tx,ty);
book[tx][ty] = 0;
book[6-tx][6-ty] = 0;
}
}
int main()
{
int i,j;
sum = 0;
memset(book,0,sizeof(book));
book[3][3] = 1;
dfs(3,3);
printf("sum==%d\n",sum/4);
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: