方格填数
如下的10个格子
+--+--+--+
| | | |
+--+--+--+--+
| | | | |
+--+--+--+--+
| | | |
+--+--+--+
(如果显示有问题,也可以参看【图1.jpg】)
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
#include <iostream>
#include <cmath>
using namespace std;
int vis[3][4];
int used[10] = {0};
int mpt[3][4];
int ans = 0;
int dir[8][2] = {1,0,-1,0,0,1,0,-1,-1,-1,1,1,-1,1,1,-1};
void dfs(int k){
int x = k/4; //除以列数得到行号
int y = k%4; //对列数取余得到列号
if(x == 3){ //说明10个格子已经都填满了数
//判断此时填满格子的方案是否满足要求,若是则ans+1,否则不变
bool flag = true;
for(int i = 0;i<3;i++){
for(int j = 0;j<4;j++){
if(vis[i][j]){
for(int p = 0;p<8;p++){
int nx = i + dir[p][0];
int ny = j + dir[p][1];
if(nx < 0 || nx > 2 || ny < 0 || ny > 3 || !vis[nx][ny]) //如果超出范围或者不可访问的点
continue;
if(abs(mpt[nx][ny] - mpt[i][j]) == 1){
flag = false;
break;
}
}
}
}
}
if(flag)
ans++;
return;
}
//如果还没有填满数
if(!vis[x][y]) //如果是地图中没有的方格
dfs(k+1);
else{
for(int i = 0;i<10;i++){
//如果数i没被使用过
if(!used[i]){
mpt[x][y] = i;
used[i] = 1;
dfs(k+1);
used[i] = 0; //递归返回后还要尝试别的方案,那在递归中使用过的数i标记应该被清除
}
}
}
}
int main(){
for(int i = 0;i<3;i++){
for(int j = 0;j<4;j++){
vis[i][j] = 1;
}
}
vis[0][0] = 0;
vis[2][3] = 0;
dfs(0);
cout << ans << endl;
return 0;
}