知识点:深搜,剪枝,位运算
这个题是9×9数独里面最难的一个题了应该,数据比较强,难度应该是蓝题,主要就是两个优化,一个是优化搜索顺序,一个是位运算,靶型数独那道题里面已经写的很详细了,这个题就不写了,两个题基本一样
#include <bits/stdc++.h>
using namespace std;
const int N = 9;
int row[N], col[N], block[3][3];
int h1[1 << N], h2[1 << N], flag;
string s;
int lowbit(int x) {
return x & -x;
}
void init() {
for (int i = 0; i < N; i++) {
row[i] = col[i] = (1 << N) - 1;
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
block[i][j] = (1 << N) - 1;
}
}
}
int get(int x, int y) {
return (row[x] & col[y] & block[x / 3][y / 3]);
}
void dfs(int k) {
if (flag) return;
if (!k) {
flag = 1;
cout << s << '\n';
return;
}
int x, y, Min = 10;
for (int i = 0; i < 9 && Min > 1; i++) {
for (int j = 0; j < 9 && Min > 1; j++) {
if (s[i * 9 + j] == '.' && h2[get(i, j)] < Min) {
Min = h2[get(i, j)];
x = i; y = j;
}
}
}
for (int i = get(x, y); i; i -= lowbit(i)) {
int t = lowbit(i);
row[x] -= t;
col[y] -= t;
block[x / 3][y / 3] -= t;
s[x * 9 + y] = '1' + h1[t];
dfs(k - 1);
row[x] += t;
col[y] += t;
block[x / 3][y / 3] += t;
s[x * 9 + y] = '.';
}
}
int main() {
for (int i = 0; i < N; i++) h1[1 << i] = i;
for (int i = 0; i < (1 << N); i++) {
int cnt = 0;
for (int j = i; j; j -= lowbit(j)) cnt++;
h2[i] = cnt;
}
while (cin >> s && s[0] != 'e') {
init();
int cnt = 0;
for (int i = 0; i < N * N; i++) {
int x = i / 9;
int y = i % 9;
if (s[i] != '.') {
int t = s[i] - '1';
row[x] -= (1 << t);
col[y] -= (1 << t);
block[x / 3][y / 3] -= (1 << t);
} else cnt++;
}
flag = 0;
dfs(cnt);
}
return 0;
}