Poj DancingLinks(3372 3074 3076)

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


 

 

你可能感兴趣的:(c,search,存储)