好吧,趁热打铁,今天写了整天的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;
}