POJ2676 Sudoku - DFS

POJ2676 Sudoku

传送门

题意:

填充未完成的数独。。。(就这么简单。。。。

思路:

爆搜即可。
可行性剪枝:用三个\(bool\)数组分别记录行、列、\(3*3\)的块中,\(9\)种数字的使用情况

AC Code:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=9+10;
char s[N][N];int mp[N][N];
int blo[N][N];bool hang[N][N],lie[N][N],kuai[N][N];
int ans[N][N];
void pre(){
	memset(ans,0,sizeof(ans));memset(mp,0,sizeof(mp));
	memset(hang,0,sizeof(hang));memset(lie,0,sizeof(lie));memset(kuai,0,sizeof(kuai));
}
bool che(int x,int y,int k){
	if(hang[x][k]||lie[y][k]||kuai[blo[x][y]][k]) return false;
	return true;
}
bool dfs(int x,int y){
	if(x==10){return true;}
	if(mp[x][y]){ bool f=0;if(y+1<=9) f=dfs(x,y+1);else f=dfs(x+1,1); return f;} 
	for(int i=1;i<=9;i++){
		if(che(x,y,i)){
			hang[x][i]=lie[y][i]=kuai[blo[x][y]][i]=1;
			ans[x][y]=i;bool f=0;
			if(y+1<=9) f=dfs(x,y+1); else f=dfs(x+1,1);
			if(f) return true;
			hang[x][i]=lie[y][i]=kuai[blo[x][y]][i]=0;
		}
	}return false;
}
int main(){
	int t;scanf("%d",&t);
	for(int i=3;i<=9;i+=3){ for(int j=1;j<=9;j++){ if(j<=3) blo[i-2][j]=blo[i-1][j]=blo[i][j]=1+(i-3); else if(j<=6) blo[i-2][j]=blo[i-1][j]=blo[i][j]=2+(i-3); else if(j<=9) blo[i-2][j]=blo[i-1][j]=blo[i][j]=3+(i-3);}}
	while(t--){
		pre();
		for(int i=1;i<=9;i++) scanf("%s",s[i]+1);
		for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) ans[i][j]=mp[i][j]=s[i][j]-'0',hang[i][mp[i][j]]=lie[j][mp[i][j]]=kuai[blo[i][j]][mp[i][j]]=1;
// 		for(int i=1;i<=9;i++) { for(int j=1;j<=9;j++) printf("%d",mp[i][j]);printf("\n");}
		dfs(1,1);
		for(int i=1;i<=9;i++){for(int j=1;j<=9;j++) printf("%d",ans[i][j]);printf("\n");}
	}
	return 0;
}
posted @ 2018-09-08 23:34  dprswdr  阅读(103)  评论(0)    收藏  举报