[回溯] 数独

有一个风靡世界的游戏,叫数独。

5????7??6
?6????5?4
?834?????
???182?4?
??1???9??
?7?369???
?????543?
1?5????9?
7??2????1

就是这个。

最low的算法。

#include<cmath>
#include<vector>
#include<cstdio>
#include<string>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 10
#define INF 2147483647
using namespace std;
int g[N][N],cnt = 0;
bool row[N][N],col[N][N],check[N][N];
//行,列,9宫格。
int sub(int x,int y){
    if (x <= 3){
        if (y <= 3) return 1;
        if (y <= 6) return 2;
        if (y <= 9) return 3;
    }
    if (x <= 6){
        if (y <= 3) return 4;
        if (y <= 6) return 5;
        if (y <= 9) return 6;
    }
    else {
        if (y <= 3) return 7;
        if (y <= 6) return 8;
        if (y <= 9) return 9;
    }
}
void init()
{
    memset(g,0,sizeof g);
    memset(row,true,sizeof row);
    memset(col,true,sizeof col);
    memset(check,true,sizeof check);
    for (int i = 1;i <= 9;i++)
    {
        char st[N];
        cin >> st;
        for (int j = 0; j < 9; j++)
            if (st[j] != '?')
            {
                cnt++;
                g[i][j+1] = st[j] - '0';
                row[i][g[i][j+1]] = false;
                col[j+1][g[i][j+1]] = false;
                check[sub(i,j+1)][g[i][j+1]] = false;
            }
    }
    cnt = 81 - cnt;
}

void Print(){
    for (int i=1;i<=9;i++){
        for (int j=1;j<=9;j++) printf("%d",g[i][j]);
        printf("\n");
    }
}

void Sdk(int x,int y,int sum){
    if (sum == cnt) {
        Print();
        return;
    }
    if (g[x][y]) {
        if (y < 9) Sdk(x,y+1,sum);
        else Sdk(x+1,1,sum);
    }else
    for (int k = 1;k <= 9;k++)
    {
        int num = sub(x,y);
        if ( row[x][k] && col[y][k]  && check[num][k])
        {
            g[x][y] = k;
            row[x][k] = false;
            col[y][k] = false;
            check[num][k] = false;
            if (y < 9) Sdk(x,y+1,sum+1);
            else Sdk(x+1,1,sum+1);
            g[x][y] = 0;
            row[x][k] = true;
            col[y][k] = true;
            check[num][k] = true;
        }
    }
}
int main(){
    init();
    Sdk(1,1,0);
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值