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\n", 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 == '\n') continue;
        if (kase) printf("\n");
        ++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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章