POJ-2676--Sudoku POJ-2918-- Tudoku

版权声明: https://blog.csdn.net/moon_sky1999/article/details/81667908

题目来源:http://poj.org/problem?id=2918  http://poj.org/problem?id=2676

剪枝+位运算。

优化策略:每行每列按照已填好的数量进行排序,优先填已经填过的多的,这样可以减少搜索的宽度。

代码:

#include <cstdio>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>

using namespace std;

int a[10][10], numl[10], numh[10], h[10], l[10], rh[10], rl[10], b[3][3], tot;

const int cmp1(const int i, const int j) { return numh[i] > numh[j]; }

const int cmp2(const int i, const int j) { return numl[i] > numl[j]; }

bool dfs(int x,int y) {
  //  cout << tot << endl;
    if (tot == 81) {
        for (int i = 1; i <= 9; ++i) {
            for (int j = 1; j <= 9; ++j) {
                cout << a[i][j];
            }
            cout << endl;
        }
        return 1;
    }
    for (int i = x, j = y; i <= 9; ++i, j = 1) {
        for (; j <= 9; ++j) {
            if (a[rh[i]][rl[j]] == 0) {
                int pos = ((h[rh[i]] | l[rl[j]]) | b[(rh[i] - 1) / 3][(rl[j] - 1) / 3]);
                if (pos == 511)return 0;
                for (int k = 1; k <= 9; ++k) {
                    if (((1 << (k - 1)) & pos) == 0) {
                        tot++;
                        a[rh[i]][rl[j]] = k;
                        h[rh[i]] |= (1 << (k - 1));
                        l[rl[j]] |= (1 << (k - 1));
                        b[(rh[i] - 1) / 3][(rl[j] - 1) / 3] |= (1 << (k - 1));
                        if (dfs(i, j))return 1;
                        tot--;
                        a[rh[i]][rl[j]] = 0;
                        h[rh[i]] -= (1 << (k - 1));
                        l[rl[j]] -= (1 << (k - 1));
                        b[(rh[i] - 1) / 3][(rl[j] - 1) / 3] -= (1 << (k - 1));
                    }
                }
                return 0;
            }
        }
    }
    return 0;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int _;
    cin >> _;
    for (int sce = 1; sce <= _; ++sce) {
        char c;
        memset(a, 0, sizeof(a));
        memset(h, 0, sizeof(h));
        memset(l, 0, sizeof(l));
        memset(b,0,sizeof(b));
        memset(numh, 0, sizeof(numh));
        memset(numl, 0, sizeof(numl));
        tot = 0;
        for (int i = 1; i <= 9; ++i) {
            for (int j = 1; j <= 9; ++j) {
                cin >> c;
                a[i][j] = c - '0';
                if (a[i][j] != 0) {
                    tot++;
                    h[i] |= (1 << (a[i][j] - 1));
                    numh[i]++;
                    l[j] |= (1 << (a[i][j] - 1));
                    numl[j]++;
                    b[(i - 1) / 3][(j - 1) / 3] |= (1 << (a[i][j] - 1));
                }
            }
            rl[i] = i;
            rh[i] = i;
        }
        sort(rl + 1, rl + 10, cmp2);
        sort(rh + 1, rh + 10, cmp1);
      //  cout << "Scenario #" << sce << ":" << endl;
        dfs(1, 1);
        cout << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/moon_sky1999/article/details/81667908