• POJ2676 Sudoku 搜索


    题意:给定一个数独的题目,0代表这个点的值未确定,现在要求填写数字进去且满足:

    1.每一行必须是1-9的集合

    2.每一列必须是1-9的集合

    3.每一个子矩阵内必须是1-9的集合

    由于给定的约束条件比较多,因此直接dfs即可。

    代码如下:

    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    char G[15][15];
    int r[15][15], c[15][15], f[15][15];
    // G用来保留整个图,R用来说明某一行有了哪些数字
    // C用来说明某一列有了哪些数
    
    bool finish;
    
    int getzone(int x, int y) {
        int a = (x - 1) / 3;
        int b = (y - 1) / 3;
        return a * 3 + b;
    }
    
    void dfs(int x, int y) {
        if (x == 9 && y == 9) {
            finish = true;
            return;
        }
        int lim;
        for (int i = x; i <= 9; ++i) {
            lim = i == x ? y + 1 : 1;
            for (int j = lim; j <= 9; ++j) {
                if (G[i][j] == 0) {
                    for (int k = 1; k <= 9; ++k) {
                        if (!r[i][k] && !c[j][k] && !f[getzone(i, j)][k]) {
                            r[i][k] = c[j][k] = f[getzone(i, j)][k] = 1, G[i][j] = k;
                            dfs(i, j);
                            if (finish) break;
                            else {
                                r[i][k] = c[j][k] = G[i][j] = f[getzone(i, j)][k] = 0;
                            }
                        }
                    }
                    goto loop;
                } else if (i == 9 && j == 9) {
                    finish = true;
                }
            }
        }
    loop:    return;
    }
    
    int main() {
        int T;
        scanf("%d", &T);
        while (T--) {
            finish = false; 
            memset(r, 0, sizeof (r));
            memset(c, 0, sizeof (c));
            memset(f, 0, sizeof (f));
            for (int i = 1; i <= 9; ++i) {
                scanf("%s", G[i]+1);
                for (int j = 1; j <= 9; ++j) {
                    G[i][j] -= '0';
                    f[getzone(i, j)][G[i][j]] = 1;
                    r[i][G[i][j]] = 1;
                    c[j][G[i][j]] = 1;
                }
            }
            dfs(1, 0); // 递归这个点,下一个点直接进入(1, 1) 
            for (int i = 1; i <= 9; ++i) {
                for (int j = 1; j <= 9; ++j) {
                    printf("%d", G[i][j]);
                }
                puts("");
            }
        }
        return 0;
    }
  • 相关阅读:
    Java 继承和重写
    Java 构造函数和函数重载
    java 面向对象
    for循环和数组例题
    java数组和函数
    java程序流程控制
    CF600C Make Palindrome
    CF600A Extract Numbers
    [NOI2007]社交网络
    SPOJ 6779 GSS7
  • 原文地址:https://www.cnblogs.com/Lyush/p/2779436.html
Copyright © 2020-2023  润新知