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;
}


 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章