HDU 1426 Sudoku Killer
就是把数字全填上,然后检验是否可以……
#include <cstdio> #include <cstring> #include <cmatn> #include <algorithm> #define rep(i,n) for(int i=1;i<=n;i++) using namespace std; int a[10][10],h[10],hs[10],ss[10],nine[10],Hash[10],q[10],st=511; int ten(int x){return (int)log2(x)+1;} void print(){rep(i,9){rep(j,8)printf("%d ",a[i][j]);printf("%d\n",a[i][9]);}} void dfs(int k){ if(k==10){print();return;} else{ int i=Hash[k],j,get,num,pos,p; pos=st&~h[i]; p=pos&-pos; h[i]|=p; j=ten(p); get=st&~(hs[i]|ss[j]|nine[(i-1)/3*3+(j-1)/3+1]); while(get){ num=get&-get; get^=num; a[i][j]=ten(num); hs[i]|=num; ss[j]|=num; nine[(i-1)/3*3+(j-1)/3+1]|=num; if(pos==p)dfs(k+1); else dfs(k); hs[i]^=num; ss[j]^=num; nine[(i-1)/3*3+(j-1)/3+1]^=num; }h[i]^=p; } } int main(){ int k=1,flag=0;char c[3]; while(scanf("%s",c)!=EOF){ if(flag)puts("");else flag=1; for(int i=0;i<10;i++)h[i]=hs[i]=ss[i]=nine[i]=Hash[i]=q[i]=0; if(c[0]=='?')a[1][1]=0; else a[1][1]=c[0]-'0'; for(int i=1;i<=9;i++) for(int j=1;j<=9;j++){ if(i==1&&j==1)continue; scanf("%s",c); if(c[0]=='?')a[i][j]=0; else a[i][j]=c[0]-'0'; } for(int i=1;i<=9;i++) for(int j=1;j<=9;j++){ Hash[i]=i; if(a[i][j]){ h[i]|=1<<(j-1); if(((hs[i]|ss[j]|nine[(i-1)/3*3+(j-1)/3+1])&(1<<(a[i][j]-1)))==1){printf("-1\n");} hs[i]|=1<<(a[i][j]-1); ss[j]|=1<<(a[i][j]-1); nine[(i-1)/3*3+(j-1)/3+1]|=1<<(a[i][j]-1); }else q[i]++; } for(int i=1;i<9;i++)for(int j=i+1;j<=9;j++) if(q[Hash[i]]>q[Hash[j]])swap(Hash[i],Hash[j]); while(q[Hash[k]]==0)k++;dfs(k); }return 0; }
愿你出走半生,归来仍是少年