一.题目链接:
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;
}