1. 程式人生 > >HUD 1426 Sudoku Killer (DFS)

HUD 1426 Sudoku Killer (DFS)

char scan == 類比 %d auth namespace step ase


鏈接 : 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; }

HUD 1426 Sudoku Killer (DFS)