2018年蓝桥杯---b组省赛D题---方格分割(dfs)

方格分割

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

如图:1,2,3 就是可行的分割法。

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

请提交该整数,不要填写任何多余的内容或说明文字。
图1
在这里插入图片描述
图2
在这里插入图片描述
图3
在这里插入图片描述
注意: dfs搜块的话形如图3的就不行了,因为dfs是一下画到底所以搜块不对!
error code(搜块):

#include<stdio.h>
#include<string.h>
using namespace std;
int dir[4][2]={
    
    {
    
    0,1},{
    
    1,0},{
    
    0,-1},{
    
    -1,0}};
int M[7][7];
int ans=0;

bool ok(){
    
    
	for(int i=1;i<=6;i++){
    
    
		for(int j=1;j<=3;j++){
    
    
			if(M[i][j]==M[6-i+1][6-j+1])return false;
		}
	}
	return true;
}

void dfs(int x,int y,int num){
    
    
	M[x][y]=1;
	if(num>18)return ;
	else if(num==18){
    
    
		if(ok()){
    
    
			ans++;
		}
		return ;
	}else{
    
    
		for(int i=0;i<4;i++){
    
    
			int xx=x+dir[i][0];
			int yy=y+dir[i][1];
			
			if(xx>=1&&xx<=6&&yy>=1&&yy<=6&&M[xx][yy]==0){
    
    
				dfs(xx,yy,num+1);
				M[xx][yy]=0;
			}
		}	
	}
}
int main(){
    
    
	memset(M,0,sizeof M);
	dfs(1,1,1);
	printf("%d",ans/4);
	return 0;
}

正确思路:
应该搜边,从中心(3,3)向边界搜索,设置两个对称方向,只要是走到边界ans++;
由于旋转对称属于一种,而自己用的是双边法,所以最后ans/2即可!
correct code:(搜边)

#include<stdio.h>
#include<string.h>
using namespace std;
int dir[4][2]={
    
    {
    
    0,1},{
    
    1,0},{
    
    0,-1},{
    
    -1,0}};
int M[7][7];
int ans=0;

void dfs(int x,int y){
    
    
	M[x][y]=1;
	M[6-x][6-y]=1;
	if(x==0||y==0||x==6||y==6){
    
    
		ans++;
		return ;
	}else{
    
    
		for(int i=0;i<4;i++){
    
    
			int xx=x+dir[i][0];
			int yy=y+dir[i][1];
			
			if(xx>=1&&xx<=6&&yy>=1&&yy<=6&&M[xx][yy]==0&&M[6-xx][6-yy]==0){
    
    
				dfs(xx,yy);
				M[xx][yy]=0;
				M[6-xx][6-yy]=0;
			}
		}
	}
}

int main(){
    
    
	memset(M,0,sizeof M);
	dfs(3,3);
	printf("%d",ans/2);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/timelessx_x/article/details/115415522
今日推荐