方格填數
如下的10個格子
填入0~9的數字。要求:連續的兩個數字不能相鄰。
(左右、上下、對角都算相鄰)
一共有多少種可能的填數方案?
請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多余的內容或說明性文字。
#include <stdio.h>
#include <math.h>
#define bool int
#define false 0
#define true 1
int flag[3][4]; //表示哪些可以填數
int mpt[3][4]; //填數
bool visit[10]; //記下被使用過的數字
int ans = 0;
void init() { //初始化
int i,j;
for(i = 0 ; i < 3 ; i ++)
for(j = 0 ; j < 4 ; j ++)
flag[i][j] = 1;
flag[0][0] = 0;
flag[2][3] = 0;
}
void Solve(){
int dir[8][2] =
{ 0, 1,//左
0, -1,//右
1, 0,//下
-1, 0,//上
1, 1,//左下
1, -1,//右下
-1, 1,//右上
-1, -1 //左上
}; //8個方向
int book = true;
for(int i = 0 ; i < 3 ; i ++){//遍歷元素
for(int j = 0 ; j < 4; j ++){
//判斷每個數周圍是否滿足
if(flag[i][j] == 0) continue;//跳過不能填的地方
for( int k = 0 ; k < 8 ; k ++){//每個方向挨個判斷 依次 左->右->下->上->左下->右下->右上->左下。
int x,y;
x = i + dir[k][0];//k在變 依次取出二維數組dir的每一行的兩個值 相加得 該方向的上的坐標 x y。
y = j + dir[k][1];
if(x < 0 || x >= 3 || y < 0 || y >= 4 || flag[x][y] == 0) continue;//若數組越界 或 當前值周圍是特殊的地方頭尾兩空 則 跳過
if(abs(mpt[x][y]/*某方向的數字 */ - mpt[i][j]/* 該數字*/) == 1) book = false;//做差 若數值相鄰的話就 book 置為0
}
}
}
if(book) ans ++;//計數
}
void dfs(int index){
int x,y;//下角標
x = index / 4;
y = index % 4;
if( x == 3){//出口 x == 3 表明 三行走完 賦值完畢
Solve();//判斷
return;
}
if(flag[x][y]){//是否為可行的地方
for(int i = 0 ; i < 10 ; i ++){
if(!visit[i]){
visit[i] = true;//標記
mpt[x][y] = i;//賦值
dfs(index+1);//遞歸下一位
visit[i] = false;//取消標記
}
}
}
else
{
dfs(index+1);
}
}
int main(){
init();
dfs(0);
printf("%d\n",ans);
return 0;
}