现在的位置: 首页 > 综合 > 正文

poj2676解题报告

2017年02月21日 ⁄ 综合 ⁄ 共 1135字 ⁄ 字号 评论关闭

题意:有一个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;
}

抱歉!评论已关闭.