好吧,趁热打铁,今天写了整天的Dancing Links,不过还老是出现种种错误~其中竟因为一个变量把整个十字链表给写成了一条长长的链了,竟然还能通过样例,TLE了好久才
发现~
三题中3372就是个模板题,不过是后来才发现有这么一个题的,先写的数独两个问题,
把他们转化成精确覆盖问题的话:
建立行:
行数为9*9*9/16*16*16,数独中,第i行j列放数字k的状态存储在图中第(i*9+j)*9+k行中
建立列:
列数为9*9+9*9+9*9+9*9/16*16+16*16+16*16,
以3*3的数独为例:
其中第一个9*9代表第i格是否已填满,
用第二个9*9确保每行的数字唯一且均出现一次
第三个9*9确保每列的数字唯一且出现一次
第四个9*9确保每宫的数字唯一出现1次
对题目建图的时候,为未确定的单元建立九行,代表九种数字的可能,为已知的元素建立确定的一行,这样由于列的限制,我们直接在表上搜索得到的答案必定包含图中确定的元素(还为这个问题纠结过呢~)。
Poj3074 Code:
#include<stdio.h> #include<string.h> #include<stdlib.h> #define N 800 #define M 350 const int head=0; const int V=N*M; int U[V],D[V],L[V],R[V],C[V]; int S[N],O[N],Row[V]; int size; int H[N]; char mapv[N]; int mapx[N]; int mapy[N]; int ak,hs; char s[10][9]; void Remove(int c) { int i,j; L[R[c]]=L[c]; R[L[c]]=R[c]; for(i=D[c];i!=c;i=D[i]){ for(j=R[i];j!=i;j=R[j]){ U[D[j]]=U[j]; D[U[j]]=D[j]; S[C[j]]--; } } } void Resume(int c) { int i,j; for(i=U[c];i!=c;i=U[i]){ for(j=L[i];j!=i;j=L[j]){ U[D[j]]=D[U[j]]=j; S[C[j]]++; } }R[L[c]]=L[R[c]]=c; } int Search(int k) { int min,i,j,c; if(R[head]==head){ ak=k;return 1; } for(min=V,c=0,i=R[head];i!=head;i=R[i]){ if(S[i]<min) min=S[i],c=i; } Remove(c); for(i=D[c];i!=c;i=D[i]){ for(j=R[i];j!=i;j=R[j]) Remove(C[j]); O[k]=Row[i]; if(Search(k+1)) return 1; for(j=L[i];j!=i;j=L[j]) Resume(C[j]); } Resume(c); return 0; } void AddNode(int f,int &h,int x) { S[x]++; C[size]=x; Row[size]=f; U[size]=U[x]; D[U[x]]=size; D[size]=x; U[x]=size; if(h==-1){ L[size]=R[size]=size; h=size; } else{ L[size]=L[h]; R[L[h]]=size; R[size]=h; L[h]=size; } size++; } int main() { int i,j,k; while(gets((char *)s),s[0][0]!='e'){ memset(S,0,sizeof(S)); for(i=0;i<=324;i++){ R[i]=i+1;L[i+1]=i; U[i]=D[i]=i; }R[324]=0; size=325;hs=0; memset(H,-1,sizeof(H)); for(i=0;i<9;i++){ for(j=0;j<9;j++){ if(s[i][j]!='.'){ AddNode(hs,H[hs],i*9+j+1); AddNode(hs,H[hs],i*9+81+s[i][j]-'0'); AddNode(hs,H[hs],j*9+162+s[i][j]-'0'); AddNode(hs,H[hs],(i/3*3+j/3)*9+243+s[i][j]-'0'); mapv[hs]=s[i][j]; mapx[hs]=i;mapy[hs]=j; hs++; } else{ for(k=1;k<=9;k++){ AddNode(hs,H[hs],i*9+j+1); AddNode(hs,H[hs],i*9+81+k); AddNode(hs,H[hs],j*9+162+k); AddNode(hs,H[hs],(i/3*3+j/3)*9+243+k); mapv[hs]=k+'0'; mapx[hs]=i;mapy[hs]=j; hs++; } } } } Search(0); for(i=0;i<ak;i++) s[mapx[O[i]]][mapy[O[i]]]=mapv[O[i]]; puts((char *)s); } return 0; }