方格填数问题
**问题描述:**填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)。
解决方案:DFS,类似于Test 3中的八皇后问题,采取第二种DFS算法求解,代码中有详细注释,如下 :
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
int visited[10] = {0} ; //标记将十个方块儿,未访问置0,已访问置1 ;
int square[3][4] ; //定义方块总格子数目
int num = 0 ; //填数的总方案 ;
bool check (int i, int j, int k) {
if (i>0 && abs(square[i-1][j]-k)==1) return false ; //判断 (i,j)的正上点(i-1,j) ; ok
if ((i>0&&j>0) && abs(square[i-1][j-1]-k)==1) return false ; //判断(i,j)的左上点(i-1,j-1) ; ok
if ((i>0&&j<3) && abs(square[i-1][j+1]-k)==1) return false ; //判断(i,j)的右上点(i-1,j+1) ; ok
if (i<2 && abs(square[i+1][j]-k)==1) return false ; //判断(i,j)的正下点(i+1,j) ; ok
if ((i<2&&j>0) && abs(square[i+1][j-1]-k)==1) return false ; //判断(i,j)的左下点(i+1,j-1) ; ok
if ((i<2&&j<3) && abs(square[i+1][j+1]-k)==1) return false ; //判断(i,j)的右下点(i+1,j+1) ; ok
if (j>0 && abs(square[i][j-1]-k)==1) return false ; //判断(i,j)的正左点(i,j-1) ; ok
if (j<3 && abs(square[i][j+1]-k)==1) return false ; // 判断(i,j)的正右点(i,j+1) ; ok
return true ;
}
void Search_Way (int i, int j ) {
if (i==2 && j==3) { //填到最后一个数就输出 ;
num++ ;
/*printf("第%d种方案为:\n",num) ;
for (int m=0; m<3; m++) {
for (int n=0; n<4; n++) {
printf("%2d",square[m][n]) ;
}
printf("\n") ;
}
printf("\n"); */
}
for (int l=0; l<10; l++) {
if (check (i, j, l) && visited[l] == 0) {
visited[l] = 1 ; //满足条件将其置1表示已访问,确保不重复 ;
square[i][j] = l ; //把这个数字填进去 ;
if (j==3) Search_Way(i+1,0) ; //这一行填完了,换行 ;
else Search_Way (i,j+1) ; //这一行没填完,继续往后面填数 ;
square[i][j] = -6 ; //不满足条件了,重置上一个填入的数 ;
visited[l] = 0 ; //并重置标记 ;
}
}
}
int main()
{
for (int i = 0; i < 3; i++) //初始化没每个方块格子
for (int j = 0; j < 4; j++)
square[i][j] = -9;
Search_Way(0, 1) ;
printf("%d\n",num) ;
return 0;
}
说明 : abs函数为求一个数的绝对值,这里在判断检查时用到了,因为如果两个数的数值相邻那么它们的绝对值就为1 ;