poj2676解题报告

题意:有一个9*9的格子 分成了9个3*3的小子格,一些位置上的已有一些数字。。现在要求你把没有数字的位置填上数,要求这个数没有出现在这个位置所在的行、列以及所在的子格

分析:

那么我们对于所有的未填写位置就可以进行一次dfs,对于每个位置枚举1~9九个数字看能不能填写,(能填写的就是符合题目的要求),对于行列比较容易,但是对于当前位置 (x,y) 所在的子格...借鉴了前辈的方法:如下:it=(x/3)*3,jt=(y/3)*3,那么 (it,jt) 就是当前位置坐在子格的左上角顶点, 可以任意列举几个点验证;;

那么上马:

 

#include<stdio.h>

#include<string.h>



int map[9][9];



int flag[82][2];//用来标记没有填写的点坐标,因为最多只有81个格子

int num;//没填写格子的个数



bool judg(int x,int y,int k)

{

	int i,j;

	//进行列和行的判断

	for(i=0;i<9;i++)

	{

		if(map[i][y]==k)return false;

		if(map[x][i]==k)return false;

	}

	//进行所在子格的判断

	int it=(x/3)*3,jt=(y/3)*3;//这里是根据x,y来计算(x,y)所在子格的左上角的点坐标

	for(i=0;i<3;i++)

		for(j=0;j<3;j++)

			if(map[i+it][j+jt]==k)

				return false;

	return true;

}



int dfs(int sum)//从没填写的子格数搜索,为0结束

{

	if(sum<0)return 1;

	int x=flag[sum][0],y=flag[sum][1];

	for(int i=1;i<=9;i++)//将(x,y)这点从1到9遍历看能否填写其中的数字

		if(judg(x,y,i))

		{

			map[x][y]=i;

			if(dfs(sum-1)) return 1;

			map[x][y]=0;

		}

	return 0;

}



int main()

{

	int T;

	int i,j;

	char c;

	scanf("%d",&T);

	getchar();

	while(T--)

	{

		num=0;

		memset(flag,0,sizeof(flag));

		for(i=0;i<9;i++)

			for(j=0;j<9;j++)

			{

				scanf("%c",&c);

				getchar();

				map[i][j]=c-'0';

				if(!map[i][j])

				{

					flag[num][0]=i;

					flag[num++][1]=j;

				}

			}

		dfs(num-1);



		for(i=0;i<9;i++)

		{

			for(j=0;j<9;j++)

				printf("%d",map[i][j]);

			printf("\n");

		}

	}

	return 0;

}


 

 

你可能感兴趣的:(poj)