HDU 1426 Sudoku Killer 枚举每一个空,深搜

题意:填数独,横竖1-9不重复,3*3方格1-9不重复(划分好的方格,看图)


想法:开始想着一行一行枚举,然后每行里面的空格再枚举,就是深搜套深搜,后来发现没必要,把空格按照顺序记录下来,往空格里面填数字,每填一个数字就判断一下,是否有不符合条件的,我们可以吧空格改成统一的一个数字,比如0或者是大于9的数字,这样如果有的空格还没有填写,在判断的时候也会返回false。


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int map[10][10],cnt;
struct node
{
	int x,y;
}point[100];
int flag;
bool judge(int num,int k)
{
	for(int i=0;i<9;i++)
	{
		if(i!=point[num].y&&map[point[num].x][i]==k) return false;
		if(i!=point[num].x&&map[i][point[num].y]==k) return false;
	}
	int x=point[num].x/3*3;
	int y=point[num].y/3*3;
	for(int i=0;i<3;i++)
	{
		for(int j=0;j<3;j++)
		{
			int rx=x+i;
			int ry=y+j; 
			if((rx!=point[num].x||ry!=point[num].y)&&map[rx][ry]==k) return false;
		}
	}
	return true;
}
void dfs(int num)
{
	if(num==cnt)
	{
		flag=1;
		return;
	}
	for(int i=1;i<10;i++)
	{
		if(judge(num,i))
		{
			map[point[num].x][point[num].y]=i;
			dfs(num+1);
			if(flag)
			{
				return;
			}
			map[point[num].x][point[num].y]=0;
		}
	}
	return;
}
int main()
{
	char g[3];
	
	int t=0;
	while(~scanf("%s",g))
	{
		cnt=0;
		if(g[0]=='?')
		{
			point[cnt].x=0;
			point[cnt++].y=0;
		}
		else map[0][0]=g[0]-'0';
		for(int i=0;i<9;i++)
		{
			for(int j=0;j<9;j++)
			{
				if(i==0&&j==0) continue;
				scanf("%s",g);
				if(g[0]=='?')
				{
					point[cnt].x=i;
					point[cnt++].y=j;
					map[i][j]=0;
				}
				else 
				{
					map[i][j]=g[0]-'0';
				}
			}
		}
		flag=0;
		dfs(0);
		if(t>0) cout<<endl;
		t++;
		for(int i=0;i<9;i++)
		{
			for(int j=0;j<9;j++)
			{
				if(j!=0) cout<<" ";
				cout<<map[i][j];
			}
			cout<<endl;
		}
	}
	return 0;
}

你可能感兴趣的:(HDU 1426 Sudoku Killer 枚举每一个空,深搜)