/*题目描述
如上面的10个格子,填入0~9的数字,不能重复(原先已经填了一部分数字),要求:连续的两个数字不能相邻(左右,上下,对角都算相邻)。例如:数字0和1不能放在一起。
问:一共有多少种可能的填数方案?
输入
输入多组测试数据。
每组测试数据有三行,第一行三个整数,第二行四个整数,第三行三个整数,之间用空格隔开,分别代表每个空格所填的数,如果原先没有数,则填-1。
输入数据保证不重复数字,不保证连续数字不相邻。
输出
每组测试数据输出一行。
输出表示方案数目的整数。
图片放反了,是一个3行4列的不规则图形,打阴影的不存在
样例输入
-1 -1 -1
-1 -1 -1 -1
-1 -1 -1
0 1 -1
-1 -1 -1 -1
-1 -1 -1
1 3 5
-1 -1 -1 -1
-1 -1 -1
样例输出
1580
0
8
*/
与数独相似,是个递归回溯的题(这是学长自己编的题给我们测试用的)
主要在于判断这个数填的时候要保证没有填过,和相邻的数不能放在一起
还要注意越界的情况
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
int a[3][4],vis[10];
int sum,n;
bool write()
{
int i,j;
memset(vis,0,sizeof(vis));
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
{
if(!(i==0&&j==0||i==2&&j==3))
{
if(scanf("%d",&n)==EOF)
return false;
a[i][j]=n;
if(a[i][j]!=-1)
{
vis[a[i][j]]=1;
}
}
}
}
return true;
}
bool judge(int r,int c,int k)
{
if(c>0&&fabs(k-a[r][c-1])==1)
return false;
if(r>0&&c>0&&fabs(k-a[r-1][c-1])==1)
return false;
if(r>0&&fabs(k-a[r-1][c])==1)
return false;
if(r>0&&c<3&&fabs(k-a[r-1][c+1])==1)
return false;
return true;
}
void DFS(int n)
{
if(n==12)
{
sum++;
return;
}
int r=n/4,c=n%4,k;
if(a[r][c] == -1)
{
for(k=0 ; k<10 ; k++)
{
if(!vis[k]&&judge(r,c,k))
{
a[r][c]=k;
vis[k] = 1;
DFS(n+1);
vis[k]=0;
a[r][c]=-1;
}
}
}
else if(judge(r,c,a[r][c]))
{
DFS(n+1);
}
}
int main()
{
a[0][0]=a[2][3]=100;
while(write())
{
sum=0;
DFS(0);
printf("%d\n",sum);
}
return 0;
}