题目描述,用程序模拟一下数独。
给你9*9的格子,空格用0表示,输出一种方案,使得每一行,每一列,以及每一宫(3*3)都分别由1-9的数字填入。输出任意方案即可。
解法,此题有各种解法,DFS即可AC。而Discuss说可以用Dancing Links,没用过额。。有空去研究研究。。
我这里用的是DFS+位运算加速判重。700ms水过。。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int mp[10][10],x[10],y[10],e[10],p[3][3]; bool flag; void DFS(int a,int b) { int i,j,t1,t2,t3,ta,tb; if (b == 10) { a++; b=1; } if (a == 10) { for (i=1; i<=9; i++) { for (j=1; j<=9; j++) { printf("%d",mp[i][j]); } printf("\n"); } flag=true; return ; } if (mp[a][b] == 0) { ta=(a-1)/3; tb=(b-1)/3; for (i=1; i<=9; i++) { t1=x[a]&e[i]; t2=y[b]&e[i]; t3=p[ta][tb]&e[i]; if (t1 != 0 || t2 != 0 || t3 != 0) continue; mp[a][b]=i; x[a]|=e[i]; y[b]|=e[i]; p[ta][tb]|=e[i]; DFS(a,b+1); if (flag == true) return ; x[a]-=e[i]; y[b]-=e[i]; p[ta][tb]-=e[i]; mp[a][b]=0; } } else { DFS(a,b+1); } } int main() { int prob,i,j; char str[120]; for (i=1; i<=9; i++) { e[i]=1<<i; } e[0]=0; scanf("%d",&prob); getchar(); while (prob--) { memset(x,0,sizeof(x)); memset(y,0,sizeof(y)); memset(p,0,sizeof(p)); for (i=1; i<=9; i++) { gets(str); for (j=1; j<=9; j++) { mp[i][j]=str[j-1]-'0'; p[(i-1)/3][(j-1)/3]+=e[mp[i][j]]; x[i]+=e[mp[i][j]]; y[j]+=e[mp[i][j]]; } } flag=false; DFS(1,1); } }