数独填空3*3
/*
3*3数独
*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=10;
bool flag=false;
int sudo[maxn][maxn];
bool vis[maxn];
void init(){
flag=0;
memset(vis,false,sizeof(vis));
}
void print(){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
printf("%d",sudo[i][j]);
}
putchar('
');
}
}
void dfs(int x,int y){
if(flag)return;
if(x==3){
flag=true;
print();
return;
}else{
if(sudo[x][y]){
if(y<2)dfs(x,y+1);
else dfs(x+1,0);
}else{
for(int i=1;i<=9;i++){
if(!vis[i]){
sudo[x][y]=i;
vis[i]=true;
if(y<2)dfs(x,y+1);
else dfs(x+1,0);
sudo[x][y]=0;
vis[i]=false;
}
}
}
}
}
int main(){
init();
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
scanf("%1d",&sudo[i][j]);
if(sudo[i][j]>=0&&sudo[i][j]<=9){
int x=sudo[i][j];
vis[x]=true;
}
}
}
dfs(0,0);
return 0;
}
数独填空9*9
给出测试组数
再给出未填时的99数独情况
输出填完的数独情况
要求每行和每列1-9只能出现一次,且局部33格中,也满足,而且3*3中每个数字需要出现一次
传送门
思路,多设了3个数组,用来记录出现的次数
然后从左上角开始搜索,从左到右,满了就到下一行的第一个,直到走到最后一行后,因为是dfs,所以记得回溯
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=10;
int G[N][N];
bool hang[N][N], lie[N][N], dyg[N][N], flag;//hang[i][x]表示第i行数字x是否用过,lie[j][x]表示第j列数字x是否用过,dyg[k][x]表示9个3*3的单元格里第k个单元格是否用过
void print(){
for(int i = 0; i < 9; i++){
for(int j = 0; j < 9; j++){
printf("%d", G[i][j]);
}
putchar('
');
}
}
void dfs(int x,int y){
if(flag) return;
if(x == 9){
flag = 1;
print();
return;
}else{
if(G[x][y]){
if(y < 8) dfs(x, y + 1);//向右
else dfs(x + 1, 0);//一行已经都搜过了,进行下一行搜索
}else{
for(int i = 1; i <= 9; i++){
if(!hang[x][i] && !lie[y][i] && !dyg[x / 3 * 3 + y / 3][i]){//如果i这个数字
G[x][y] = i;//保存搜到的数
hang[x][i] = lie[y][i] = dyg[x / 3 * 3 + y / 3][i] = 1;//标记
if(y < 8) dfs(x, y + 1);
else dfs(x + 1, 0);
G[x][y] = 0;//回溯
hang[x][i] = lie[y][i] = dyg[x / 3 * 3 + y / 3][i] = 0;
}
}
}
}
}
int main(){
int t;
cin >> t;
while(t--){
memset(hang, false, sizeof(hang));
memset(lie, false, sizeof(lie));
memset(dyg, false, sizeof(dyg));
flag = 0;
for(int i = 0;i < 9; i++){
for(int j = 0; j < 9; j++){
scanf("%1d", &G[i][j]);
if(G[i][j] != 0){
int v = G[i][j];
hang[i][v] = lie[j][v] = dyg[i / 3 * 3 + j / 3][v] = 1;
}
}
}
dfs(0, 0);//从第1行第一列开始搜索
}
return 0;
}