【POJ2676】Sudoku(类似于八皇后问题的DFS)

题面:【POJ2676】Sudoku

题意:

给你若干个不完整的数独(空的地方用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;
}




版权声明:转载请注明地址

猜你喜欢

转载自blog.csdn.net/chenxiaoran666/article/details/80214391