HDU - 5547 数独(回溯法)

题目链接:HDU-5547 http://acm.hdu.edu.cn/showproblem.php?pid=5547


 正所谓:骗分过样例,暴力出奇迹。

解题思想(暴力出奇迹(DFS+回溯)):

1. 依次在空格里面填上“1~9”,并检查这个数字是否合法(其所在的行、列,以及3X3的子区域里不存在重复的数字)。如果合法,则前进到下一个格子。

2. 如果在某个格子里,从“1”到“9”都不合法,这说明前面某个格子填错了。这时就回退到上一格,继续试。例如,如果上一格已填的数字是3,就继续试4,5,6,… 是否合法。如果找到一个合法的数字,则又前进到下一格。如果找不到,说明前面还有格子也填错了,则继续回退到更前面一格,… 如此反复。

4. 如果这个数独是有解的,我们总会遇到“蒙对了”的情况。

 

HDU 的这题实在是太坑了,题目描述里有一句:Each test case starts with an empty line followed by 4 lines,没仔细看输入样例里也没有空行 。66666666666666666。告辞,我错了。

#include <iostream>
#include <string>
using namespace std;

int M[4][4];
bool flag = false;

int check(int row, int column, int x) {
    for (int i = 0; i < 4; i++) {
        if (M[i][column] == x || M[row][i] == x)
            return 0;
    }
    int r = row / 2 * 2, c = column / 2 * 2;
    for (int i = r; i < r + 2; i++) {
        for (int j = c; j < c + 2; j++) {
            if (M[i][j] == x) return 0;
        }
    }
    return 1;
}


void DFS(int row, int column) {
    if (row == 4) {
        flag = true;
        return;
    }

    if (M[row][column] == -6) {
        int i;
        for (i = 1; i <= 4; i++) {
            if (check(row, column, i)) {
                M[row][column] = i;
                DFS(row + (column + 1) / 4, (column + 1) % 4);
                if (flag) return;    
            }
        }
        if (i == 5) {
            M[row][column] = -6;
            return;
        }
    }
    DFS(row + (column + 1) / 4, (column + 1) % 4);
}
int main() {
    int i = 1,n;
    cin >> n;    string s;
    cin.ignore();
    while (n--) {
        flag = false;
        for (int i = 0; i < 4; i++) {
            getline(cin, s);
            if (s.empty()) {
                i--;
                continue;
            }
            for (int j = 0; j < 4; j++) {
                M[i][j] = s[j]-'0';
            }
        }
        DFS(0, 0);
        cout << "Case #" << i++ << ":" << endl;
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                cout << M[i][j];
            }
            cout << endl;
        }
    }
    return 0;
}

 

posted @ 2019-02-07 17:50  czc1999  阅读(239)  评论(1编辑  收藏  举报