题意:给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;
}