题解: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);

}
posted @ 2025-07-26 14:37  WMWD  阅读(23)  评论(0)    收藏  举报