poj2676

13 篇文章 0 订阅

题目意思很简单就是填充1-9数字到给定的9方格使之满足每一行、每一列、每一个小3方格都是1-9的数字,注意题目要求只需求出一个满足上述条件的矩阵即可。典型的深搜+剪枝。此题要注意两点:

1)剪枝的关键在于将不满足上述条件的情况直接舍弃

2)注意此题存在回溯

直接贴代码(代码中有详细注释):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Max 20
int record[Max][Max];
bool flag[Max][Max];
bool Is_ok;
int Case;
bool dfs(int x,int y){ //只要发现一个满足条件的方格,则返回,故设计成bool,方便递归返回
	if(x==9 && y==0)
		return true;
	if(y==9){
		if(dfs(x+1,0))
			return true;
		else
			return false;
	}
	if(flag[x][y]){
		if(dfs(x,y+1))
			return true;
		else
			return false;
	}
	else{  //注意此处是关键点:将该行该列该小方格内存在的数字标识
		int num[Max]={0};
		for(int i=0;i<=8;i++) // 标识该行的数字
			if(flag[x][i])
				num[record[x][i]]++;
		for(int i=0;i<=8;i++) // 标识该列的数字
			if(flag[i][y])
				num[record[i][y]]++;
		int tx=x/3,ty=y/3;
		for(int i=tx*3;i<=tx*3+2;i++) // 标识该小方格的数字
			for(int j=ty*3;j<=ty*3+2;j++)
				if(flag[i][j])
					num[record[i][j]]++;
		flag[x][y]=true;
		for(int i=1;i<=9;i++)
			if(num[i]==0){ //若不存在该数字
				record[x][y]=i; 
				if(dfs(x,y+1)) 
					return true;
			} 
		flag[x][y]=false; //回溯,注意体会
		return false;
	}
}	
				
	

int main(){
	scanf("%d",&Case);
	getchar();
	while(Case--){
		memset(flag,0,sizeof(flag));
		for(int i=0;i<9;i++){
			for(int j=0;j<9;j++){
				record[i][j]=getchar()-'0';
				if(record[i][j]>0)
					flag[i][j]=true;
			}
			getchar();
		}
        dfs(0,0);
		for(int i=0;i<9;i++){
			for(int j=0;j<9;j++)
				printf("%d",record[i][j]);
			printf("\n");
		}
	}
	return 0;
}
	


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值