A - Sudoku POJ - 2676(dfs)

在这里插入图片描述在这里插入图片描述
题意:给99的格子,并且分为三个33的小块,每个小块里面必须有1–9数字,并且每行每列也必须有1–9数字,并且不得重复;
现在给出了99中的一些格子已经被填充了;
思路:这道题肯定是dfs枚举所有可能;
首先搞明白这个问题:
对于一个Map[10][10]的宫格,那么i/3和j/3和第几块k有什么关系:
在这里插入图片描述
可以发现3
(i/3)+j/3就是等于第k个格子;
所以找到了能标记块里面的标记数字了;
所以具体就看代码吧;这道题确实比较巧妙,有点像八皇后问题,也是通过找规律标记实现dfs;
AC代码:

#include<iostream>
#include<cstdio>
using namespace std;
int row[10][10];//表示第i行放了x这个数字吗
int  col[10][10];//表示第j列放了y这个数字吗
int grid[10][10];//表示第3*(i/3)+j/3个格子 放了z这个数字吗
char Map[15][15]; 
int gridn(int x,int y){
    
    //算这个坐标在哪块
	return 3*(x/3)+y/3; 
}
int flag;
void dfs(int times){
    
    //通过这个参数,我能够算出来目前枚举到的是哪个坐标
	if(times>=81){
    
    
		flag=1;return;//因为数字已经放完了,所以标记一下,以便后面没必要在枚举了
	}
	if(flag)return ;
	int r=times/9;//算当前坐标,这里比较巧妙
	int c=times%9;
	if(Map[r][c]!='0') {
    
    //如果这个位置已经有数字了,那么就枚举下一个位置
		if(flag)return ;
	   dfs(times+1);
    }
	else {
    
    
		for(int i=1;i<=9;i++){
    
    
			int num=gridn(r,c);
			  if(!row[r][i]&&!col[c][i]&&!grid[num][i]){
    
    
			  	Map[r][c]=char(i+'0');
			  	row[r][i]=1;col[c][i]=1;grid[num][i]=1;
			  	dfs(times+1);
			  	if(flag)return;
			  	Map[r][c]='0';
			  	row[r][i]=0;col[c][i]=0;grid[num][i]=0;
			  }
		}
	}
}
int main(){
    
    
	int n;
	scanf("%d",&n);
	while(n--){
    
    
		flag=0;
		for(int i=0;i<10;i++){
    
    
			  for(int j=0;j<10;j++){
    
    
			  	  row[i][j]=col[i][j]=grid[i][j]=0;
			  }
		}
		  for(int i=0;i<9;i++) scanf("%s",&Map[i]);
		    for(int i=0;i<9;i++){
    
    
		  	  for(int j=0;j<9;j++){
    
    
		  	  	   if(Map[i][j]!='0'){
    
    
		  	  	     row[i][Map[i][j]-'0']=1;
		  	  	     col[j][Map[i][j]-'0']=1;
		  	  	     int num=gridn(i,j);
		  	  	     grid[num][Map[i][j]-'0']=1;
					}
				}
		  }
		  dfs(0);
		  for(int i=0;i<9;i++){
    
    
		  	  printf("%s\n",Map[i]);
		  }
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_44555205/article/details/104652797