题解 UVA1309 【Sudoku】

时间:2021-08-11
本文章向大家介绍题解 UVA1309 【Sudoku】,主要包括题解 UVA1309 【Sudoku】使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

这道题正解是DLX,但也可以用搜索来做,可以锻炼码力,需要加几个剪枝就能过,见代码

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=16;
int map[1<<N],ones[1<<N],st[N][N];
char str[N][N+1],mstr[N*N+1][N][N+1];
int mst[N*N+1][N][N],mst2[N*N+1][N][N];
void draw(int x,int y,int c)
{
	str[x][y]=c+'A';
	for(int i=0;i<N;++i)
	{
		st[x][i]&=~(1<<c);
		st[i][y]&=~(1<<c);
	}
	int xx=x/4*4,yy=y/4*4;
	for(int i=0;i<4;++i)
		for(int j=0;j<4;++j)
			st[xx+i][yy+j]&=~(1<<c);
	st[x][y]=1<<c;
}
inline int lowbit(int x)
{
	return x&-x	;
}
bool dfs(int cnt)
{
	if(!cnt)return 1;
	int mcnt=cnt;
	memcpy(mst[mcnt],st,sizeof(st));
	memcpy(mstr[mcnt],str,sizeof(str));
	
	for(int i=0;i<N;++i)
		for(int j=0;j<N;++j)
			if(str[i][j]=='-')		
			{
				if(!st[i][j])
				{
					memcpy(st,mst[mcnt],sizeof(st));
					memcpy(str,mstr[mcnt],sizeof(str));
					return 0;
				}
				if(ones[st[i][j]]==1)
				{
					draw(i,j,map[st[i][j]]);
					--cnt;
				}
			}
	
	for(int i=0;i<N;++i)
	{
		int sor=0,sand=(1<<N)-1;
		int drawn=0;
		for(int j=0;j<N;++j)
		{
			int s=st[i][j];
			sand&=~(sor&s);
			sor|=s;
			if(str[i][j]!='-')drawn|=st[i][j];
		}
		if(sor!=(1<<N)-1)
		{
			memcpy(st,mst[mcnt],sizeof(st));
			memcpy(str,mstr[mcnt],sizeof(str));
			return 0;
		}
		for(int j=sand;j;j-=lowbit(j))
		{
			int t=lowbit(j);
			if(!(drawn&t))
			{
				for(int k=0;k<N;++k)
					if(st[i][k]&t)
					{
						draw(i,k,map[t]);
						cnt--;
						break;
					}
			}
		}
	}
	
	for(int i=0;i<N;++i)
	{
		int sor=0,sand=(1<<N)-1;
		int drawn=0;
		for(int j=0;j<N;++j)
		{
			int s=st[j][i];
			sand&=~(sor&s);
			sor|=s;
			if(str[j][i]!='-')drawn|=st[j][i];
		}
		if(sor!=(1<<N)-1)
		{
			memcpy(st,mst[mcnt],sizeof(st));
			memcpy(str,mstr[mcnt],sizeof(str));
			return 0;
		}
		for(int j=sand;j;j-=lowbit(j))
		{
			int t=lowbit(j);
			if(!(drawn&t))
			{
				for(int k=0;k<N;++k)
					if(st[k][i]&t)
					{
						draw(k,i,map[t]);
						cnt--;
						break;
					}
			}
		}
	}
	
	for(int i=0;i<N;++i)
	{
		int sor=0,sand=(1<<N)-1;
		int drawn=0;
		for(int j=0;j<N;++j)
		{
			int sx=i/4*4,sy=i%4*4;
			int dx=j/4,dy=j%4;
			int s=st[sx+dx][sy+dy];
			sand&=~(sor&s);
			sor|=s;
			if(str[sx+dx][sy+dy]!='-')drawn|=st[sx+dx][sy+dy];
		}
		if(sor!=(1<<N)-1)
		{
			memcpy(st,mst[mcnt],sizeof(st));
			memcpy(str,mstr[mcnt],sizeof(str));
			return 0;
		}
		for(int j=sand;j;j-=lowbit(j))
		{
			int t=lowbit(j);
			if(!(drawn&t))
			{ 
				for(int k=0;k<N;++k)
				{
					int sx=i/4*4,sy=i%4*4;
					int dx=k/4,dy=k%4;
					if(st[sx+dx][sy+dy]&t)
					{
						draw(sx+dx,sy+dy,map[t]);
						cnt--;
						break;
					}
				}
			}
		}
	}
	
	if(!cnt)return 1;
	
	int x,y,ms=100;
	for(int i=0;i<N;++i)
		for(int j=0;j<N;++j)
			if(str[i][j]=='-'&&ones[st[i][j]]<ms)
			{
				ms=ones[st[i][j]];
				x=i,y=j;
			}
	
	memcpy(mst2[mcnt],st,sizeof(st));
	for(int i=st[x][y];i;i-=lowbit(i))
	{
		memcpy(st,mst2[mcnt],sizeof(st));
		draw(x,y,map[lowbit(i)]);
		if(dfs(cnt-1))return 1;
	}
	memcpy(st,mst[mcnt],sizeof(st));
	memcpy(str,mstr[mcnt],sizeof(str));
	return 0;
}
int main()
{
	for(int i=0;i<N;++i)map[1<<i]=i;
	for(int i=0;i<(1<<N);++i)ones[i]=ones[i>>1]+(i&1);
	int KASE=0;
	while(scanf("%s",str[0])!=EOF)
	{
		if(KASE++)puts("");
		for(int i=1;i<N;++i)scanf("%s",str[i]);
		
		for(int i=0;i<N;++i)
			for(int j=0;j<N;++j)
				st[i][j]=(1<<N)-1;
		int tot=0;
		for(int i=0;i<N;++i)
			for(int j=0;j<N;++j)
				if(str[i][j]!='-')draw(i,j,str[i][j]-'A');
				else ++tot;
		dfs(tot);
		for(int i=0;i<N;++i)printf("%s\n",str[i]);
	}
	return 0;
}

原文地址:https://www.cnblogs.com/wewnb/p/15130064.html