问题 B: 数独(九宫格经典问题+dfs)

问题 B: 数独(九宫格经典问题+dfs)

题目描述
这个游戏只有一个规则:
将格子填满使得每一行,每一列,和每一个小的九宫格,恰好包含1-9这9个数字

正是由于规则简单而又变化多端,数独一时间风靡全球。
现在,我们希望你能编写一个程序解决数独问题。

输入
输入数据一共9行,每行有9个字符。
输入数据描述了一个待解决的数独,其中,“?”表示数独中的空缺。
我们的输入数据总保证有唯一解。
输出
输出一共9行,每行9个数字,表示你的答案。
样例输入 Copy
5????7??6
?6????5?4
?834?????
???182?4?
??1???9??
?7?369???
?????543?
1?5????9?
7??2????1
样例输出 Copy
514927386
967831524
283456179
659182743
321574968
478369215
892615437
135748692
746293851

 

 

思路:dfs。符合条件继续搜,不符合递推回来。

#pragma GCC optimize(3 , "Ofast" , "inline")
 
#include <bits/stdc++.h>
 
#define rep(i , a , b) for(register int i=(a);i<=(b);i++)
#define per(i , a , b) for(register int i=(a);i>=(b);i--)
 
 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int , int> pi;
 
template<class T>
inline void read (T &x) {
    x = 0;
    int sign = 1;
    char c = getchar ();
    while (c < '0' || c > '9') {
        if ( c == '-' ) sign = - 1;
        c = getchar ();
    }
    while (c >= '0' && c <= '9') {
        x = x * 10 + c - '0';
        c = getchar ();
    }
    x = x * sign;
}
 
const int maxn = 2e5 + 10;
const int inf = int (1e9);
const ll INF = ll (1e18);
const double PI = acos (- 1);
const int mod = 1e9+7;
const double eps = 1e-8;
 
char s[20][20];
bool visc[10][10];
bool visr[10][10];
bool visg[10][10];
int ans[20][20];
 
 
bool dfs(int x,int y) {
    if(x==10) return true;
    bool f=0;
    if(ans[x][y]) {
        if(y==9) f=dfs (x+1,1);
        else f=dfs (x,y+1);
        return f;
    }
    int cnt = (x-1)/3*3+(y-1)/3+1;
    rep (i,1,9) {
        if(!visc[x][i]&&!visr[y][i]&&!visg[cnt][i]) {
            visc[x][i]=1;
            visr[y][i]=1;
            visg[cnt][i]=1;
            ans[x][y]=i;
            if(y==9) f=dfs (x+1,1);
            else f=dfs (x,y+1);
            if(f) return f;
            visc[x][i]=0;
            visr[y][i]=0;
            visg[cnt][i]=0;
            ans[x][y]=0;
        }
    }
    return false;
}
int main () {
    rep (i,1,9) {
        scanf ("%s",s[i]+1);
        rep (j,1,9) {
            if(s[i][j]=='?') {
                ans[i][j]=0;
                continue;
            }
            else ans[i][j]=s[i][j]-'0';
            visc[i][ans[i][j]]=1;
            visr[j][ans[i][j]]=1;
            visg[(i-1)/3*3+(j-1)/3+1][ans[i][j]]=1;
        }
    }
    dfs(1,1);
    rep (i,1,9) {
        rep (j,1,9) {
            printf ("%d",ans[i][j]);
        }
        printf ("\n");
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值