Suduko

版权声明:作为一个蒟蒻,转载时请通知我这个蒟蒻 https://blog.csdn.net/zyszlb2003/article/details/89412503

数独问题转化为精确覆盖问题基本思路

详情参考:算法实践——舞蹈链(Dancing Links)算法求解数独 - 万仓一黍 - 博客园

POJ2676

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<bitset>
using namespace std;
const int N=3310;
const int M=331;
const int g[9][9]=
{
	{0,0,0,1,1,1,2,2,2,},
	{0,0,0,1,1,1,2,2,2,},
	{0,0,0,1,1,1,2,2,2,},
	{3,3,3,4,4,4,5,5,5,},
	{3,3,3,4,4,4,5,5,5,},
	{3,3,3,4,4,4,5,5,5,},
	{6,6,6,7,7,7,8,8,8,},
	{6,6,6,7,7,7,8,8,8,},
	{6,6,6,7,7,7,8,8,8,},
};
int num,r[N],l[N],d[N],u[N],col[N],sz[M],head;
int a[10][10];
void remove(int p)
{
	l[r[p]]=l[p],r[l[p]]=r[p];
	for(int i=u[p];i!=p;i=u[i])
		for(int j=r[i];j!=i;j=r[j])
			u[d[j]]=u[j],d[u[j]]=d[j];
}
void resume(int p)
{
	l[r[p]]=r[l[p]]=p;
	for(int i=u[p];i!=p;i=u[i])
		for(int j=r[i];j!=i;j=r[j])
			u[d[j]]=d[u[j]]=j;
}
void link(int j)
{
	++num;
	u[num]=u[j];d[num]=j;col[num]=j;
	u[d[num]]=d[u[num]]=num;++sz[j];
	if(!head)head=num;
	else l[num]=num-1,r[num-1]=num;
}
void make(int i,int j,int k)//i行,j列,填k 
{
	head=0;
	link(i*9+j+1),link(81+i*9+k),link(162+j*9+k),link(243+g[i][j]*9+k);
	l[head]=num;r[num]=head;
}
bool bk;
void dance()
{
	if(!r[0])
	{
		for(int i=1;i<=9;i++)
		{
			for(int j=1;j<=9;j++)
			{
				printf("%d",a[i][j]);
			}
			puts("");
		}
		bk=true;return ;
	}
	int p=r[0],x,y;
	for(int i=r[p];i;i=r[i])if(sz[i]<sz[p])p=i;
	remove(p);
	for(int i=d[p];i!=p;i=d[i])
	{
		if(0<col[i]&&col[i]<=81)x=col[i];
		else if(81<col[i]&&col[i]<=162)y=col[i];
		for(int j=r[i];j!=i;j=r[j])
		{
			remove(col[j]);
			if(0<col[j]&&col[j]<=81)x=col[j];
			else if(81<col[j]&&col[j]<=162)y=col[j];
		}
		a[(x-1)/9+1][(x-1)%9+1]=(y-1)%9+1;dance();if(bk)return ;
		for(int j=r[i];j!=i;j=r[j])resume(col[j]);
	}
	resume(p);
}
char s[10];
int main()
{
	int t;scanf("%d",&t);
	while(t--)
	{
		num=324;bk=false;//memset(r,0,sizeof(r));memset(l,0,sizeof(l)),memset(u,0,sizeof(u));
		//memset(d,0,sizeof(d));head=0;memset(sz,0,sizeof(sz));memset(col,0,sizeof(col));
		memset(sz,0,sizeof(sz));head=0;
		for(int i=0;i<=num;i++)l[i]=i-1,r[i]=i+1,u[i]=d[i]=i;
		l[0]=num;r[num]=0;
		for(int i=0;i<9;i++)
		{
			scanf("%s",s);
			for(int j=0;j<9;j++)
			{
				int x=s[j]-'0';
				if(x)make(i,j,x);
				else for(int k=1;k<=9;k++)make(i,j,k);
			}
		}
		dance();
	}
	return 0;
}

POJ3074

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<bitset>
using namespace std;
const int N=3310;
const int M=331;
const int g[9][9]=
{
	{0,0,0,1,1,1,2,2,2,},
	{0,0,0,1,1,1,2,2,2,},
	{0,0,0,1,1,1,2,2,2,},
	{3,3,3,4,4,4,5,5,5,},
	{3,3,3,4,4,4,5,5,5,},
	{3,3,3,4,4,4,5,5,5,},
	{6,6,6,7,7,7,8,8,8,},
	{6,6,6,7,7,7,8,8,8,},
	{6,6,6,7,7,7,8,8,8,},
};
int num,r[N],l[N],d[N],u[N],col[N],sz[M],head;
int a[10][10];
void remove(int p)
{
	l[r[p]]=l[p],r[l[p]]=r[p];
	for(int i=u[p];i!=p;i=u[i])
		for(int j=r[i];j!=i;j=r[j])
			u[d[j]]=u[j],d[u[j]]=d[j],--sz[col[j]];
}
void resume(int p)
{
	l[r[p]]=r[l[p]]=p;
	for(int i=u[p];i!=p;i=u[i])
		for(int j=r[i];j!=i;j=r[j])
			u[d[j]]=d[u[j]]=j,++sz[col[j]];
}
void link(int j)
{
	++num;
	u[num]=u[j];d[num]=j;col[num]=j;
	u[d[num]]=d[u[num]]=num;++sz[j];
	if(!head)head=num;
	else l[num]=num-1,r[num-1]=num;
}
void make(int i,int j,int k)//i行,j列,填k 
{
	head=0;
	link(i*9+j+1),link(81+i*9+k),link(162+j*9+k),link(243+g[i][j]*9+k);
	l[head]=num;r[num]=head;
}
bool bk;
void dance()
{
	if(bk)return ;
	if(!r[0])
	{
		for(int i=1;i<=9;i++)
		{
			for(int j=1;j<=9;j++)
			{
				printf("%d",a[i][j]);
			}
		}
		bk=true;return ;
	}
	int p=r[0],x,y;
	for(int i=r[p];i;i=r[i])if(sz[i]<sz[p])p=i;
	remove(p);
	for(int i=u[p];i!=p;i=u[i])
	{
		if(0<col[i]&&col[i]<=81)x=col[i];
		else if(81<col[i]&&col[i]<=162)y=col[i];
		for(int j=r[i];j!=i;j=r[j])
		{
			remove(col[j]);
			if(0<col[j]&&col[j]<=81)x=col[j];
			else if(81<col[j]&&col[j]<=162)y=col[j];
		}
		a[(x-1)/9+1][(x-1)%9+1]=(y-1)%9+1;dance();if(bk)return ;
		for(int j=r[i];j!=i;j=r[j])resume(col[j]);
	}
	resume(p);
}
char s[90];
int main()
{
	while(scanf("%s",s))
	{
		if(s[0]=='e')break;
		num=324;bk=false;//memset(r,0,sizeof(r));memset(l,0,sizeof(l)),memset(u,0,sizeof(u));
		//memset(d,0,sizeof(d));head=0;memset(sz,0,sizeof(sz));memset(col,0,sizeof(col));
		memset(sz,0,sizeof(sz));head=0;
		for(int i=0;i<=num;i++)l[i]=i-1,r[i]=i+1,u[i]=d[i]=i;
		l[0]=num;r[num]=0;
		int len=0;
		for(int i=0;i<9;i++)
		{
			for(int j=0;j<9;j++)
			{
				int x=s[len]-(s[len]=='.'?'.':'0');len++;
				if(x)make(i,j,x);
				else for(int k=1;k<=9;k++)make(i,j,k);
			}
		}
		dance();puts("");
	}
	return 0;
}

POJ3076

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
const int g[20][20]=
{
	{0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,},
	{0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,},
	{0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,},
	{0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,},
	{4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,},
	{4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,},
	{4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,},
	{4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,},
	{8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11},
	{8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11},
	{8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11},
	{8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11},
	{12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,},
	{12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,},
	{12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,},
	{12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,},
};
const int N=1100;
const int M=17000;
int l[M],r[M],u[M],d[M],col[M],row[M],sz[N],num,head;
void remove(int p)
{
	r[l[p]]=r[p];l[r[p]]=l[p];
	for(int i=u[p];i!=p;i=u[i])
		for(int j=r[i];j!=i;j=r[j])
			u[d[j]]=u[j],d[u[j]]=d[j],--sz[col[j]];
}
void resume(int p)
{
	r[l[p]]=l[r[p]]=p;
	for(int i=u[p];i!=p;i=u[i])
		for(int j=r[i];j!=i;j=r[j])
			u[d[j]]=d[u[j]]=j,++sz[col[j]];
}
void link(int i,int j)
{
	++num;
	u[num]=u[j];d[num]=j;++sz[j];
	u[d[num]]=d[u[num]]=num;col[num]=j;row[num]=i;
	if(!head)head=num;
	else l[num]=num-1,r[num-1]=num;
}
void make(int i,int j,int k)
{
	int len=(i*16+j)*16+k;head=0;
	link(len,i*16+j+1),link(len,256+i*16+k),link(len,512+j*16+k),link(len,768+g[i][j]*16+k);
	l[head]=num;r[num]=head;
}
int ans[N],tot,a[21][21];char s[21][21];
bool dance(int k)
{
	if(!r[0]){tot=k-1;return true;}
	int p=r[0];
	for(int i=r[p];i;i=r[i])if(sz[p]>sz[i])p=i;
	remove(p);
	for(int i=u[p];i!=p;i=u[i])
	{
		ans[k]=row[i];
		for(int j=r[i];j!=i;j=r[j])remove(col[j]);
		if(dance(k+1))return true;
		for(int j=l[i];j!=i;j=l[j])resume(col[j]);
	}
	resume(p);
	return false;
}
int main()
{
	while(scanf("%s",s[0])!=EOF)
	{
		for(int i=1;i<16;i++)scanf("%s",s[i]);
		num=1024;//memset(r,0,sizeof(r));memset(l,0,sizeof(l)),memset(u,0,sizeof(u));
		//memset(d,0,sizeof(d));head=0;memset(sz,0,sizeof(sz));memset(col,0,sizeof(col));
		memset(sz,0,sizeof(sz));//memset(h,-1,sizeof(h));
		for(int i=0;i<=num;i++)l[i]=i-1,r[i]=i+1,u[i]=d[i]=i;
		l[0]=num;r[num]=0;
		for(int i=0;i<16;i++)
		{
			for(int j=0;j<16;j++)
			{
				int x=s[i][j]-(s[i][j]=='-'?'-':'A'-1);
				if(x)make(i,j,x);
				else for(int k=1;k<=16;k++)make(i,j,k);
			}
		}
		dance(0);
		for(int i=0;i<=tot;i++)
		{
			int x=(ans[i]-1)/16/16;
			int y=(ans[i]-1)/16%16;
			int c=(ans[i]-1)%16;
			a[x][y]='A'+c;
		}
		for(int i=0;i<16;i++)
		{
			for(int j=0;j<16;j++)printf("%c",a[i][j]);
			puts("");
		} 
		puts("");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zyszlb2003/article/details/89412503