• HUD 1426 Sudoku Killer (DFS)



    **链接 : ** Here!

    **思路 : ** 记录下所有 "?" , 出现的位置, 然后 $DFS$ 一下, 对于每个位置来说都可以填充 $9$ 种数值, 然后对于判断填充是否合法需要三个标记数组来辅助记录. $visR[i][num] = 1, 代表第 i 行num值已经出现过, visC[i][num] = 1, 代表第 i 列num值已经出现过, visB[i][num] = 1, 代表第 i 小块 num值已经出现过$. 计算小块的标号只需要 $x / 3 * 3 + y / 3 $ 即可.

    类比 : ** 与之相似的题目是 hihocoder 1321, 但是这样做会 T, 所以 hihocoder 需要用舞蹈链**

    **注意 : ** 此题读入十分恶心, 最好在写完读入操作后检查一下. 还需要注意, 如果是已经给出的值 (即非'?'), 需要先标记一下.


    /*************************************************************************
        > File Name: 1426-Sudoku-Killer.cpp
        > Author: 
        > Mail: 
        > Created Time: 2017年11月29日 星期三 17时16分39秒
     ************************************************************************/
    
    #include <bits/stdc++.h>
    using namespace std;
    
    #define MAX_N 20
    struct Point {
        int x, y;
    } pt[110];
    int node_cnt = 0;
    int G[MAX_N][MAX_N];
    int visR[MAX_N][MAX_N] = {0}; 
    int visC[MAX_N][MAX_N] = {0}; 
    int visB[MAX_N][MAX_N] = {0};
    int ok = 0;
    
    void clear() {
        node_cnt = 0;
        ok = 0;
        memset(G, 0, sizeof(G));
        memset(visR, 0, sizeof(visR));
        memset(visC, 0, sizeof(visC));
        memset(visB, 0, sizeof(visB));
    }
    int cal_block(int x, int y) {
        return (x / 3 * 3 + y / 3);
    }
    bool check(int x, int y, int block, int num) {
        return !(visR[x][num] || visC[y][num] || visB[block][num]);
    }
    void set_pt(int x, int y, int block, int num) {
        visR[x][num] = visC[y][num] = visB[block][num] = 1;
    }
    void move_pt(int x, int y, int block, int num) {
        visR[x][num] = visC[y][num] = visB[block][num] = 0;
    }
    void dfs(int step) {
        if (ok) return;
        if (step == node_cnt) {
            for (int i = 0 ; i < 9 ; ++i) {
                for (int j = 0 ; j < 8 ; ++j) {
                    printf("%d ", G[i][j]);
                }
                printf("%d
    ", G[i][8]);
            }
            ok = 1;
            return;
        }
        for (int i = 1 ; i <= 9 ; ++i) {
            int x = pt[step].x;
            int y = pt[step].y;
            int block = cal_block(x, y);
            if (!check(x, y, block, i)) continue;
            set_pt(x, y, block, i);
            int t_val = G[x][y];
            G[x][y] = i;
            dfs(step + 1);
            G[x][y] = t_val;
            move_pt(x, y, block, i);
        }
        return;
    }
    int main() {
        int kase = 0;
        char ch;
        while (scanf("%c", &ch) != EOF) {
            if (ch == '
    ') continue;
            if (kase) printf("
    ");
            ++kase;
    
            G[0][0] = (ch == '?' ? 0 : (ch - '0'));
            if (G[0][0] == 0) {
                pt[node_cnt].x = 0;
                pt[node_cnt].y = 0;
                ++node_cnt;
            } else {
                set_pt(0, 0, cal_block(0, 0), G[0][0]);
            }
            for (int i = 1 ; i < 9 ; ++i) {
                scanf("%c", &ch);
                if (ch == ' ') {
                    --i; continue;
                }
                G[0][i] = (ch == '?' ? 0 : (ch - '0'));
                if (G[0][i] == 0) {
                    pt[node_cnt].x = 0;
                    pt[node_cnt].y = i;
                    ++node_cnt;
                } else {
                    set_pt(0, i, cal_block(0, i), G[0][i]);
                }
            }
            for (int i = 1 ; i < 9 ; ++i) {
                getchar();
                for (int j = 0 ; j < 9 ; ++j) {
                    scanf("%c", &ch);
                    if (ch == ' ') {
                        --j; continue;
                    }
                    G[i][j] = (ch == '?' ? 0 : (ch - '0'));
                    if (G[i][j] == 0) {
                        pt[node_cnt].x = i;
                        pt[node_cnt].y = j;
                        ++node_cnt;
                    } else {
                        set_pt(i, j, cal_block(i, j), G[i][j]);
                    }
                }
            }
            dfs(0);
            clear();
        }
        return 0;
    }
    
  • 相关阅读:
    事务管理
    QQ邮箱开启SMTP方法如何授权
    基于JavaMail的Java邮件发送:简单邮件发送
    Spring MVC 响应视图(六)
    Spring MVC 数据绑定 (四)
    Spring MVC Spring中的Model (五)
    Spring MVC 拦截器 (十)
    Spring MVC 异常处理 (九)
    Java 骚操作--生成二维码
    Java MD5校验与RSA加密
  • 原文地址:https://www.cnblogs.com/WArobot/p/7922009.html
Copyright © 2020-2023  润新知