一.题目链接:

POJ-3074

二.题目大意:

就是普通的数独问题.

三.分析:

暂时没学跳舞链,这里用 dfs 写了一下.

这里需要预处理出好多东西,不然 T 死你.

以及各种优化,二进制 + 位运算 和 每次优先选取可能数少的点.

详见代码.

四.代码实现:

#include <set>
#include <map>
#include <ctime>
#include <queue>
#include <cmath>
#include <stack>
#include <bitset>
#include <vector>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define eps 1e-8
#define lc k * 2
#define rc k * 2 + 1
#define pi acos(-1.0)
#define ll long long
#define ull unsigned long long
using namespace std;

const int M = (int)1e6;
const int mod = 99991;
const int inf = (1<<9) - 1;

char str[81];
char mp[10][10];
int num[inf + 1];///状态 U 的选择数
map <int, int> figure;///处理出 2^n
int row[10], col[10], grid[10];
int id[10][10] =
{
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 1, 1, 1, 2, 2, 2, 3, 3, 3},
    {0, 1, 1, 1, 2, 2, 2, 3, 3, 3},
    {0, 1, 1, 1, 2, 2, 2, 3, 3, 3},
    {0, 4, 4, 4, 5, 5, 5, 6, 6, 6},
    {0, 4, 4, 4, 5, 5, 5, 6, 6, 6},
    {0, 4, 4, 4, 5, 5, 5, 6, 6, 6},
    {0, 7, 7, 7, 8, 8, 8, 9, 9, 9},
    {0, 7, 7, 7, 8, 8, 8, 9, 9, 9},
    {0, 7, 7, 7, 8, 8, 8, 9, 9, 9}
};///grid的坐标转换

int lowbit(int x)
{
    return x&(-x);
}

void init()
{
    int cnt;
    for(int i = 0; i <= inf; ++i)
    {
        cnt = 0;
        for(int j = i; j; j -= lowbit(j))
            ++cnt;
        num[i] = cnt;
    }
    for(int i = 0; i < 9; ++i)
        figure[1<<i] = i + 1;
}

void work()
{
    for(int i = 1; i <= 9; ++i)
        row[i] = col[i] = grid[i] = inf;
    for(int i = 1; i <= 9; ++i)
    {
        for(int j = 1; j <= 9; ++j)
        {
            mp[i][j] = str[(i - 1) * 9 + j - 1];
            if(mp[i][j] == '.')
                mp[i][j] = '0';
            else
            {
                row[i] ^= 1<<(mp[i][j] - '1');
                col[j] ^= 1<<(mp[i][j] - '1');
                grid[id[i][j]] ^= 1<<(mp[i][j] - '1');
            }
        }
        mp[i][10] = '\0';
    }
}

pair <int, int> get_min()
{
    int x, y, Min, U;
    x = y = Min = 10;
    for(int i = 1; i <= 9; ++i)
    {
        for(int j = 1; j <= 9; ++j)
        {
            if(mp[i][j] != '0')
                continue;
            U = row[i] & col[j] & grid[id[i][j]];
            if(!U)
                return make_pair(-1, -1);
            if(num[U] < Min)
            {
                Min = num[U];
                x = i, y = j;
            }
        }
    }
    return make_pair(x, y);
}

bool dfs(int x, int y)
{
    int U = row[x] & col[y] & grid[id[x][y]];
    for(int i = U; i; i -= lowbit(i))
    {
        mp[x][y] = figure[lowbit(i)] + '0';
        row[x] ^= lowbit(i);
        col[y] ^= lowbit(i);
        grid[id[x][y]] ^= lowbit(i);
        pair <int, int> p = get_min();
        if(p.first == -1)
        {
            mp[x][y] = '0';
            row[x] ^= lowbit(i);
            col[y] ^= lowbit(i);
            grid[id[x][y]] ^= lowbit(i);
            continue;
        }
        if(p.first == 10 || dfs(p.first, p.second))
            return 1;
        mp[x][y] = '0';
        row[x] ^= lowbit(i);
        col[y] ^= lowbit(i);
        grid[id[x][y]] ^= lowbit(i);
    }
    return 0;
}

/**
.2738..1..1...6735.......293.5692.8...........6.1745.364.......9518...7..8..6534.
......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.
end
**/

int main()
{
//    freopen("input.txt", "r", stdin);
    init();
    while(~scanf("%s", str) && str[0] != 'e')
    {
        work();
        pair <int, int> p = get_min();
        dfs(p.first, p.second);
        for(int i = 1; i <= 9; ++i)
            printf("%s", mp[i] + 1);
        printf("\n");
    }
//    fclose(stdin);
    return 0;
}