题解 | #Sudoku#2023华为编程笔试牛客网练习C
Sudoku
https://www.nowcoder.com/practice/78a1a4ebe8a34c93aac006c44f6bf8a1?tpId=37&rp=1&ru=%2Fexam%2Foj%2Fta&qru=%2Fexam%2Foj%2Fta&sourceUrl=%2Fexam%2Foj%2Fta%3Fdifficulty%3D5%26page%3D1%26pageSize%3D50%26search%3D%26tpId%3D37%26type%3D37&difficulty=5&judgeStatus=&tags=&title=&gioEnter=menu
#include<bits/stdc++.h>
#define N 9
using namespace std;
bool row[N][N],col[N][N],block[N][N];
int a[N][N];
bool flag=false;
void init()
{
memset(row,0,sizeof row);
memset(col,0,sizeof col);
memset(block,0,sizeof block);
flag=false;
}
int getBlock(int x,int y)
{
return (x/3)*3+(y/3);
}
bool check(int x,int y,int num)
{
return !row[x][num]&&!col[y][num]&&!block[getBlock(x,y)][num];
}
void dfs(int x,int y)
{
if(flag) return ;
if(x==N)
{
flag=true;
return ;
}
if(a[x][y])
{
if(y==N-1) dfs(x+1,0);
else dfs(x,y+1);
}
else
{
for(int i=0;i<N;i++)
{
if(check(x,y,i))
{
a[x][y]=i+1;
row[x][i]=col[y][i]=block[getBlock(x,y)][i]=true;
if(y==N-1) dfs(x+1,0);
else dfs(x,y+1);
if(flag) return ;
row[x][i]=col[y][i]=block[getBlock(x,y)][i]=false;
a[x][y]=0;
}
}
}
}
int main()
{
init();
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
{
cin>>a[i][j];
if(a[i][j])
{
int num=a[i][j]-1;
row[i][num]=true;
col[j][num]=true;
block[getBlock(i,j)][num]=true;
}
}
dfs(0,0);
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
return 0;
}
数独是一个数字逻辑游戏,玩家需要根据已知的数字填充空缺位,使得每一行、每一列、每一个小九宫格内都包含1到9的数字,且不重复。
解题思路是使用深搜的方法。
首先,初始化,用三个布尔数组记录每一行、每一列、每一个小九宫格内的数字是否出现过。
然后,我们从第一行第一列开始,判断当前位置是否已经有数字:
- 如果已经有数字,则直接判断下一个位置;
- 如果没有数字,则从1到9枚举每一个数字,判断这个数字是否在该行、该列、该小九宫格内都没有出现过。
如果满足要求,就把该数字放入该位置并标记为已出现,继续判断下一个位置;
如果不满足要求,则回溯,重置该位置的数字,并把该数字在行、列、小九宫格内的标记重置。
如果我们搜索到最后一行最后一列,说明我们已经成功搜索到了一种可能的解,此时就可以退出搜索。
最后,如果
搜索成功,我们就可以输出最终的数独盘面。
总体来说,数独问题可以使用深搜来解决,每一个位置都枚举所有可能的数字,如果满足要求,就继续搜索,如果不满足要求,就回溯。直到找到一种可能的解,就可以输出结果。
#华为笔试##华为校招##华为OD##大厂编程##华为编程#
联想公司福利 1481人发布