题目意思很简单就是填充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;
}