方格填數
如下的10個格子
+--+--+--+
| | | |
+--+--+--+--+
| | | | |
+--+--+--+--+
| | | |
+--+--+--+
(如果顯示有問題,也可以參看【圖1.jpg】)
填入0~9的數字。要求:連續的兩個數字不能相鄰。
(左右、上下、對角都算相鄰)
一共有多少種可能的填數方案?
請填寫表示方案數目的整數。
注意:你提交的應該是一個整數,不要填寫任何多餘的內容或說明性文字。
分析
搜索+判斷
#include<stdio.h>
#include<stdlib.h>
int v[12]={0},a[3][4],b[3][4],s=0;//v數字是否使用,a方格是否可填,b填入數據
void solve()//判斷是否可行
{
int dir[8][2]={0,1,1,0,0,-1,-1,0,1,1,-1,-1,1,-1,-1,1};
int f=0,i,j,k;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
if(a[i][j])
for(k=0;k<8;k++)//循環判斷八個相鄰方向是否連續
{
int x=i+dir[k][0];
int y=j+dir[k][1];
if(x>2||x<0||y<0||y>3||!a[x][y])//如果越界就跳出本次循環
continue;
if(abs(b[x][y]-b[i][j])==1)//如果兩個數連續,就不符合要求
f=1;
}
if(!f)
s++;
}
void dfs(int n)//搜索所有填數方案
{
int x,y,i;
x=n/4;//橫座標
y=n%4;//豎座標
if(x==3)//如果填數完成就判斷是否可行
{
solve();
return;
}
if(a[x][y])//如果本座標可以填數
{
for(i=0;i<10;i++)//尋找沒有被使用的數字
if(!v[i])
{
b[x][y]=i;//填入數字
v[i]=1;//標記填入
dfs(n+1);//進入下一層
v[i]=0;//回溯
}
}
else
dfs(n+1);//如果填過或者不可填數,就直接進入下一層
}
int main()
{
int i,j;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
a[i][j]=1;//標記可填
a[0][0]=a[2][3]=0;//特殊處理
dfs(0);
printf("%d\n",s);
}