题解:B4279 [蓝桥杯青少年组国赛 2023] 数独填数
B4279 [蓝桥杯青少年组国赛 2023] 数独填数 DFS解法题解
这道题有点像八皇后的解题思路。只不过规则是数独的规则。
思路
首先,先清楚数独的规则:
每一行包含数字 \(1\sim9\) 且不重复;每一列包含数字 \(1\sim9\) 且不重复;每一个 \(3 \times 3\) 方块(粗线划分)包含数字 \(1\sim9\) 且不重复。
对于以上三条规则我们可以用桶数组来记录和判断数字是否重复。
用 \(ht_{i,j}\) 二维数组来表示第 \(i\) 行的数字 \(j\) 是否存在。用 \(st_{i,j}\) 二维数组来表示第 \(i\) 列的数字 \(j\) 是否存在。用 \(xt_{i,j}\) 二维数组来表示第 \(i\) 个方块内数字 \(j\) 是否存在,为了方便表示,我们可以设一个数组 \(ch\) 用来表示第 \(i\) 行第 \(j\) 列的数是第几方块。
//部分代码
bool ht[10][10],st[10][10],xt[10][10];
int prox[100],proy[100],k;//prox 表示空格的行坐标,proy 表示列坐标。k 表示空格数量
char gt[10][10];//用字符数组存储数独,方便输入。
int ch[10][10]={
{1,1,1,2,2,2,3,3,3},
{1,1,1,2,2,2,3,3,3},
{1,1,1,2,2,2,3,3,3},
{4,4,4,5,5,5,6,6,6},
{4,4,4,5,5,5,6,6,6},
{4,4,4,5,5,5,6,6,6},
{7,7,7,8,8,8,9,9,9},
{7,7,7,8,8,8,9,9,9},
{7,7,7,8,8,8,9,9,9}
};//初始化
然后,用 DFS 来搜索每一个空格,对于空格 \((x,y)\) 我们枚举数字 \(i(1 \le i \le 9)\)。如果 \(ht_{x,i}\) 与 \(st_{y,i}\) 与 \(xt_{ch_{x,y},i}\) 都为 \(0\),即数字 \(i\) 在其行,列,方块内都没出现。那将空格 \((x,y)\) 暂设置为 \(i\),并继续搜索下一个空格。如果没有符合条件的 \(i\) 回溯上一个空格。
//dfs部分代码
int tx=prox[x],ty=proy[x];
for(int i=1;i<=9;i++){
if(!ht[tx][i]&&!st[ty][i]&&!xt[ch[tx][ty]][i]){
ht[tx][i]=1;
st[ty][i]=1;
xt[ch[tx][ty]][i]=1;
gt[tx][ty]=i+'0';
dfs(x+1);
ht[tx][i]=0;
st[ty][i]=0;
xt[ch[tx][ty]][i]=0;
gt[tx][ty]='.';
}
}
记得在搜索下一个空格前一定要将数组 \(ht\),\(st\),\(xt\) 都标记为 \(1\),表示数字 \(i\) 在其行,列,方块上出现。回溯后记得全部标记为 \(0\)。
最后,当所有空格都填上数字时,就可以输出了。因为数独有唯一解,所以可以直接输出。
完整代码:
#include<bits/stdc++.h>
using namespace std;
bool ht[10][10],st[10][10],xt[10][10];
int ch[10][10]={
{1,1,1,2,2,2,3,3,3},
{1,1,1,2,2,2,3,3,3},
{1,1,1,2,2,2,3,3,3},
{4,4,4,5,5,5,6,6,6},
{4,4,4,5,5,5,6,6,6},
{4,4,4,5,5,5,6,6,6},
{7,7,7,8,8,8,9,9,9},
{7,7,7,8,8,8,9,9,9},
{7,7,7,8,8,8,9,9,9}
};
int prox[100],proy[100],k;
char gt[10][10];
void dfs(int x){
if(x>k){
for(int i=0;i<9;i++){
for(int j=0;j<9;j++)cout<<gt[i][j];
cout<<endl;
}
exit(0);
};
int tx=prox[x],ty=proy[x];
for(int i=1;i<=9;i++){
if(!ht[tx][i]&&!st[ty][i]&&!xt[ch[tx][ty]][i]){
ht[tx][i]=1;
st[ty][i]=1;
xt[ch[tx][ty]][i]=1;
gt[tx][ty]=i+'0';
dfs(x+1);
ht[tx][i]=0;
st[ty][i]=0;
xt[ch[tx][ty]][i]=0;
gt[tx][ty]='.';
}
}
return ;
}
int main(){
for(int i=0;i<9;i++)
{
cin>>gt[i];
for(int j=0;j<9;j++){
if(gt[i][j]!='.'){
ht[i][gt[i][j]-'0']=1;
st[j][gt[i][j]-'0']=1;
xt[ch[i][j]][gt[i][j]-'0']=1;
}
else{
prox[++k]=i;
proy[k]=j;
}
}
}
dfs(1);
}

浙公网安备 33010602011771号