题意:
给你若干个不完整的数独(空的地方用0表示),请你把它们补全(对于每个数独只需输出一种方案)。
解析:
看见这题,我自然而然地想到了八皇后问题,而这题似乎比八皇后问题还要更为简单。
我们可以用a[]数组来存储每一列出现过的数字,用b[]数组来存储每一行出现过的数字,用c[]数组来存储每一大格出现过的数字,这样就可以进行搜索了。
代码如下:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#define max(x,y) (x>y?x:y)
#define min(x,y) (x<y?x:y)
int s[10][10];
bool a[10][10],b[10][10],c[10][10];//a[]数组存储每一列出现过的数字,b[]数组存储每一行出现过的数字,c[]数组存储每一大格出现过的数字
int read()
{
int x=0,f=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if(ch=='-') f=-1,ch=getchar();
while(ch>='0'&&ch<='9') (x*=10)+=ch-'0',ch=getchar();
return x*=f;
}
void write(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
int w(int x,int y) {return (x-1)/3*3+(y-1)/3+1;}//求出当前位置在哪一大格
bool dfs(int x,int y)//搜索与回溯
{
if(x>9) return true;
if(y>9) return dfs(x+1,1);
if(s[x][y]) return dfs(x,y+1);
for(int i=1;i<=9;i++) if(!a[x][i]&&!b[y][i]&&!c[w(x,y)][i]) {a[x][i]=b[y][i]=c[w(x,y)][i]=true,s[x][y]=i;if(dfs(x,y+1)) return true;a[x][i]=b[y][i]=c[w(x,y)][i]=false,s[x][y]=0;}
return false;
}
int get_num()//读入单个数字
{
char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
return ch-'0';
}
int main()
{
int T=read();
while(T--)
{
memset(a,false,sizeof(a)),memset(b,false,sizeof(b)),memset(c,false,sizeof(c));
for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) a[i][s[i][j]=get_num()]=b[j][s[i][j]]=c[w(i,j)][s[i][j]]=true;
dfs(1,1);
for(int i=1;i<=9;i++,putchar('\n')) for(int j=1;j<=9;j++) write(s[i][j]);
}
return 0;
}
版权声明:转载请注明地址