【DLX算法】poj2676 Sudoku
DLX算法求解精确覆盖问题模板。赛场上可以参见白书。
#include<cstdio> #include<cstring> #include<vector> using namespace std; const int sub[10][10]={ {0,0,0,0,0,0,0,0,0,0}, {0,1,1,1,2,2,2,3,3,3}, {0,1,1,1,2,2,2,3,3,3}, {0,1,1,1,2,2,2,3,3,3}, {0,4,4,4,5,5,5,6,6,6}, {0,4,4,4,5,5,5,6,6,6}, {0,4,4,4,5,5,5,6,6,6}, {0,7,7,7,8,8,8,9,9,9}, {0,7,7,7,8,8,8,9,9,9}, {0,7,7,7,8,8,8,9,9,9} }; int hlb[12],hub[12],llb[12],lub[12]; const int maxn=4*9*9+5; const int maxr=9*9*9+5; const int maxnode=9*9*9*4+maxn+5; //ÐбàºÅ´Ó1¿ªÊ¼£¬ÁбàºÅΪ1~n£¬½áµã0ÊDZíÍ·½áµã£»½áµã1~nÊǸ÷Áж¥²¿µÄÐéÄâ½áµã struct DLX{ int n,sz;//ÁÐÊý£¬½áµã×ÜÊý int S[maxn];//¸÷ÁнáµãÊý int row[maxnode],col[maxnode];//¸÷½áµãËùÔÚµÄÐÐÁбàºÅ int L[maxnode],R[maxnode],U[maxnode],D[maxnode]; int ansd,ans[maxr];//½â void init(int n){//nÊÇÁÐÊý this->n=n; for(int i=0;i<=n;++i){ U[i]=i; D[i]=i; L[i]=i-1; R[i]=i+1; } R[n]=0; L[0]=n; sz=n+1; memset(S,0,sizeof(S)); } void addRow(int r,vector<int> columns){ int first=sz; for(int i=0;i<columns.size();++i){ int c=columns[i]; L[sz]=sz-1; R[sz]=sz+1; D[sz]=c; U[sz]=U[c]; D[U[c]]=sz; U[c]=sz; row[sz]=r; col[sz]=c; ++S[c]; ++sz; } R[sz-1]=first; L[first]=sz-1; } //˳×ÅÁ´±íA£¬±éÀú³ýsÍâµÄÆäËûÔªËØ #define FOR(i,A,s) for(int i=A[s];i!=s;i=A[i]) void remove(int c){ L[R[c]]=L[c]; R[L[c]]=R[c]; FOR(i,D,c){ FOR(j,R,i){ U[D[j]]=U[j]; D[U[j]]=D[j]; --S[col[j]]; } } } void restore(int c){ FOR(i,U,c){ FOR(j,L,i){ ++S[col[j]]; U[D[j]]=j; D[U[j]]=j; } } L[R[c]]=c; R[L[c]]=c; } bool dfs(int d){ // printf("%d",d); if(R[0]==0){//ÕÒµ½½â ansd=d;//¼Ç¼½âµÄ³¤¶È return 1; } //ÕÒ½áµãÊý×îСµÄÁÐc int c=R[0];//µÚÒ»¸öδɾ³ýµÄÁÐ FOR(i,R,0){ if(S[i]<S[c]){ c=i; } } remove(c);//ɾ³ýµÚcÁÐ FOR(i,D,c){//ÓýáµãiËùÔÚÐи²¸ÇµÚcÁÐ ans[d]=row[i]; FOR(j,R,i){ remove(col[j]);//ɾ³ý½áµãiËùÔÚÐÐÄܸ²¸ÇµÄËùÓÐÆäËûÁÐ } if(dfs(d+1)){ return 1; } FOR(j,L,i){ restore(col[j]);//»Ö¸´½áµãiËùÔÚÐÐÄܸ²¸ÇµÄÆäËûËùÓÐÁÐ } } restore(c);//»Ö¸´µÚcÁÐ return 0; } bool solve(vector<int>& v){ v.clear(); if(!dfs(0)){ return 0; } for(int i=0;i<ansd;++i){ v.push_back(ans[i]); } return 1; } }dlx; char s[12][12]; int a[12][12]; int mah[1005],mal[1005],mav[1005]; int encode(int a,int b,int c){ return a*81+b*9+c+1; } void decode(int code,int &a,int &b,int &c){ --code; c=code%9;code/=9; b=code%9;code/=9; a=code; } int main(){ int zu; // freopen("poj2676.in","r",stdin); // freopen("poj2676.out","w",stdout); memset(hlb,0x7f,sizeof(hlb)); memset(llb,0x7f,sizeof(llb)); for(int i=1;i<=9;++i){ for(int j=1;j<=9;++j){ hlb[sub[i][j]]=min(hlb[sub[i][j]],i); hub[sub[i][j]]=max(hub[sub[i][j]],i); llb[sub[i][j]]=min(llb[sub[i][j]],j); lub[sub[i][j]]=max(lub[sub[i][j]],j); } } scanf("%d",&zu); for(;zu;--zu){ for(int i=1;i<=9;++i){ scanf("%s",s[i]+1); } int hang=0,lie=0; for(int i=1;i<=9;++i){ for(int j=1;j<=9;++j){ a[i][j]=s[i][j]-'0'; } } dlx.init(9*9*4); for(int i=1;i<=9;++i){ for(int j=1;j<=9;++j){ for(int k=1;k<=9;++k){ if(!a[i][j] || a[i][j]==k){ vector<int> columns; columns.push_back(encode(0,i-1,j-1)); columns.push_back(encode(1,i-1,k-1)); columns.push_back(encode(2,j-1,k-1)); columns.push_back(encode(3,sub[i][j]-1,k-1)); dlx.addRow(encode(i-1,j-1,k-1),columns); } } } } vector<int> ans; dlx.solve(ans); for(int i=0;i<ans.size();++i){ int r,c,v; decode(ans[i],r,c,v); a[r+1][c+1]=v+1; } for(int i=1;i<=9;++i){ for(int j=1;j<9;++j){ printf("%d",a[i][j]); } printf("%d\n",a[i][9]); } } return 0; }
——The Solution By AutSky_JadeK From UESTC
转载请注明出处:http://www.cnblogs.com/autsky-jadek/