题目大意:
16*16的数独。
思路分析:
多说无益.
想说的就是dancing links 的行是按照
第一行第一列填 1
第一行第二列填 2
……
第一行第十五列填15
第一行第二列填 1
……
第二行。。。。
列的纺织则是
第一行放1,第一行放2,。。第十六行放16.。。第一列放1.。第一列放2.。。第十六列放16.。第一块区域放1 。。。。然后在最后81位就是放自己的位置,准确的说就是 r*m+c。
#include
#include
#include
#include
#define maxn 16*16*16*16*16*4+5 #define inf 0x3f3f3f3f using namespace std; int n=16*16*9,m=16*16*4,p; int map[16*16*16+5][16*16*4+5]; int L[maxn],R[maxn],D[maxn],U[maxn],S[maxn],O[maxn],col[maxn],row[maxn],head,cnt; int num; void dancing_links_init() { head=0; memset(S,0,sizeof S); for(int i=head;i<=m;i++) { R[i]=(i+1)%(m+1); L[i]=(i-1+m+1)%(m+1); U[i]=D[i]=i; } cnt=m+1; for(int i=1;i<=n;i++) { int rowh=-1; for(int j=1;j<=m;j++) { if(map[i][j]) { S[j]++; U[cnt]=U[j]; D[U[j]]=cnt; U[j]=cnt; D[cnt]=j; row[cnt]=i; col[cnt]=j; if(rowh==-1) { L[cnt]=R[cnt]=cnt; rowh=cnt; } else { L[cnt]=L[rowh]; R[L[rowh]]=cnt; R[cnt]=rowh; L[rowh]=cnt; } cnt++; } } } } void Remove(const int &c) { L[R[c]]=L[c]; R[L[c]]=R[c]; for(int i=D[c];i!=c;i=D[i]) { for(int j=R[i];j!=i;j=R[j]) { U[D[j]]=U[j]; D[U[j]]=D[j]; --S[col[j]]; } } } void Resume(const int &c) { for(int i=U[c];i!=c;i=U[i]) { for(int j=L[i];j!=i;j=L[j]) { ++S[col[j]]; U[D[j]]=j; D[U[j]]=j; } } L[R[c]]=c; R[L[c]]=c; } bool dfs(const int &k)//可行解 { if(head==R[head]) { sort(O,O+256); for(int i=0;i<256;i++) { printf("%c",O[i]-i*16+'A'-1); if(i%16==15)puts(""); } puts(""); return true; } int mx=inf,cur=0; for(int t=R[head];t!=head;t=R[t]) { if(S[t]
=num)return; int mx=inf,cur=0; for(int t=R[head];t!=head;t=R[t]) { if(S[t]