方格填数
如下的10个格子
+--+--+--+
| | | |
+--+--+--+--+
| | | | |
+--+--+--+--+
| | | |
+--+--+--+
(如果显示有问题,也可以参看【图1.jpg】)
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; int num[3][4],sum; int vis[10]; int dx[]= {-1,-1,0,-1}; int dy[]= {0,1,-1,-1}; int A(int x,int y)//判断它的正上方,右上方,左上方,正左方四个方向即可 { for(int i=0; i<4; i++) { int xx=x+dx[i]; int yy=y+dy[i]; if(xx<0||xx>2||yy<0||yy>3||num[xx][yy]==-1)//超出范围的不算,第一个和最后一个格子不用算 continue; else if(abs(num[xx][yy]-num[x][y])==1)//如果相差为1,即表示相邻 { return 0; } } return 1; } void dfs(int step) { int x=step/4; int y=step%4; if(step>10) { int ok=0; for(int i=0; i<3; i++) { for(int j=0; j<4; j++) { if((i==0&&j==0)||(i==2&&j==3)) continue; if(!A(i,j)) { ok=1; break; } } if(ok) break; } if(!ok) { sum++; // for(int i=0; i<3; i++) // { // for(int j=0; j<4; j++) // { // printf("%d",num[i][j]); // } // printf("\n"); // } // printf("\n"); } return ; } for(int i=0; i<10; i++) { //num[x][y]=i; if(!vis[i])//没有用过i这个数 { num[x][y]=i; vis[i]=1; dfs(step+1); vis[i]=0; } } } int main() { memset(num,-1,sizeof(num));//初始化全为-1,方便处理第一个和最后一个格子 sum=0; dfs(1); printf("%d\n",sum); return 0; }
还可以这样写
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; int num[3][4],sum; int vis[10]; int dx[]= {-1,-1,0,-1}; int dy[]= {0,1,-1,-1}; int A(int x,int y)//判断它的正上方,右上方,左上方,正左方四个方向即可 { for(int i=0; i<4; i++) { int xx=x+dx[i]; int yy=y+dy[i]; if(xx<0||xx>2||yy<0||yy>3||num[xx][yy]==-1)//超出范围的不算,第一个和最后一个格子不用算 continue; else if(abs(num[xx][yy]-num[x][y])==1)//如果相差为1,即表示相邻 { return 0; } } return 1; } void dfs(int step) { int x=step/4; int y=step%4; if(step>10) { sum++; // for(int i=0; i<3; i++) // { // for(int j=0; j<4; j++) // { // printf("%d",num[i][j]); // } // printf("\n"); // } return ; } for(int i=0; i<10; i++) { num[x][y]=i;//先填一个数 if(!vis[i]&&A(x,y))//然后判断填的这个数是不是和前面的数不相邻 //不相邻再递归填下一个数,直至找到一种复合的情况,在回溯去找另一种复合的情况,和八皇后思路一样 { vis[i]=1; dfs(step+1); vis[i]=0; } } } int main() { memset(num,-1,sizeof(num));//初始化全为-1,方便处理第一个和最后一个格子 sum=0; dfs(1); printf("%d\n",sum); return 0; }