题目链接:
http://poj.org/problem?id=2676
题目意思:
数独填数。
解题思路:
可以o(1)检查是否可能。
row[i][j]表示第i行的数j是否已填。(false表示未填,true表示已填)
col[i][j]表示第i列的数j是否已填。(false表示未填,true表示已填)
bl[i][j]表示第i块的数j是否已填。(false表示未填,true表示已填)将9*9的格子分成9块,0~8 根据坐标(i,j)可以推出相应的块,i/3*3+j/3
经过上面处理后,直接dfs就行了。
代码:
//#include<CSpreadSheet.h> #include<iostream> #include<cmath> #include<cstdio> #include<sstream> #include<cstdlib> #include<string> #include<string.h> #include<cstring> #include<algorithm> #include<vector> #include<map> #include<set> #include<stack> #include<list> #include<queue> #include<ctime> #include<bitset> #define eps 1e-6 #define INF 0x3f3f3f3f #define PI acos(-1.0) #define ll __int64 #define LL long long #define lson l,m,(rt<<1) #define rson m+1,r,(rt<<1)|1 #define M 1000000007 #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define Maxn 12 bool row[Maxn][Maxn],col[Maxn][Maxn],bl[Maxn][Maxn];//bl[i][j]表示第i块的j是否占用 int n; char save[Maxn][Maxn]; int ans[Maxn][Maxn]; void init() { memset(row,false,sizeof(row)); memset(col,false,sizeof(col)); memset(bl,false,sizeof(bl)); } bool flag; void dfs(int cx,int cy) { if(flag) return ; if(cx>=9) { for(int i=0;i<9;i++) { for(int j=0;j<9;j++) printf("%d",ans[i][j]); putchar('\n'); } flag=true; return ; } int b=cx/3*3+cy/3; //块号 if(save[cx][cy]!='0') //已经填了,不用再填 { int xx=cx,yy=cy+1; if(yy>=9) { xx++; yy=0; } dfs(xx,yy); return ; } for(int i=1;i<=9;i++) //每个方格尝试 { if(row[cx][i]||col[cy][i]||bl[b][i]) continue; ans[cx][cy]=i; row[cx][i]=true; col[cy][i]=true; bl[b][i]=true; int xx=cx,yy=cy+1; if(yy>=9) { xx++; yy=0; } dfs(xx,yy); row[cx][i]=false; col[cy][i]=false; bl[b][i]=false; if(flag) return ; } } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); scanf("%d",&n); while(n--) { for(int i=0;i<9;i++) scanf("%s",save[i]); init(); for(int i=0;i<9;i++) { for(int j=0;j<9;j++) { if(save[i][j]!='0') { int cur=save[i][j]-'0'; int x=i/3*3+j/3; //块号 row[i][cur]=true; col[j][cur]=true; bl[x][cur]=true; ans[i][j]=cur; } } } flag=false; dfs(0,0); } return 0; }