题目大意:
解题思路:
这题不难,但是学到了一个特别实用的搜索小技巧:先从状态少的开始搜索
- 因为搜索树上虽然节点个数相同剪枝会剪掉更多的节点。
感性理解一下,如果在某个地方存在剪枝,把情况较多的节点放在它后面枚举显然比放在前面快
AC代码:
#include <bits/stdc++.h>
using namespace std;
int cnt, ans = -1;
int a[10][10], row[10][10], column[10][10], pal[10][10], zp[100][4];
struct P {
int row, sum;
} zero[10];
bool cmp(P lhs, P rhs) {return lhs.sum < rhs.sum;}
int _pal(int tx, int ty) {
if (1 <= tx && tx <= 3) {
if (1 <= ty && ty <= 3) return 1;
else if (4 <= ty && ty <= 6) return 2;
else return 3;
}
else if (4 <= tx && tx <= 6) {
if (1 <= ty && ty <= 3) return 4;
else if (4 <= ty && ty <= 6) return 5;
else return 6;
}
else {
if (1 <= ty && ty <= 3) return 7;
else if (4 <= ty && ty <= 6) return 8;
else return 9;
}
}
int _point(int tx, int ty) {
if (tx == 1 || ty == 1 || tx == 9 || ty == 9) return 6;
else if (tx == 2 || ty == 2 || tx == 8 || ty == 8) return 7;
else if (tx == 3 || ty == 3 || tx == 7 || ty == 7) return 8;
else if (tx == 4 || ty == 4 || tx == 6 || ty == 6) return 9;
else return 10;
}
void dfs(int num, int sum) {
if (num == cnt + 1) {
ans = max(ans, sum);
return;
}
for (int i = 1; i <= 9; i++) {
if (!row[zp[num][0]][i] && !column[zp[num][1]][i] && !pal[zp[num][3]][i]) {
row[zp[num][0]][i] = column[zp[num][1]][i] = pal[zp[num][3]][i] = 1;
dfs(num + 1, sum + i * zp[num][2]);
row[zp[num][0]][i] = column[zp[num][1]][i] = pal[zp[num][3]][i] = 0;
}
}
return;
}
int main() {
int sum = 0;
for (int i = 1; i <= 9; i++) zero[i].row = i;
for (int i = 1; i <= 9; i++)
for (int j = 1; j <= 9; j++) {
cin >> a[i][j];
if (a[i][j]) {
row[i][a[i][j]] = column[j][a[i][j]] = pal[_pal(i, j)][a[i][j]] = 1, sum += _point(i, j) * a[i][j];
}
else
zero[i].sum++;
}
sort (zero + 1, zero + 9 + 1, cmp);
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= 9; j++) {
if (a[zero[i].row][j]) continue;
zp[++cnt][0] = zero[i].row, zp[cnt][1] = j, zp[cnt][2] = _point(zero[i].row, j), zp[cnt][3] = _pal(zero[i].row, j);
}
}
dfs(1, sum);
cout << ans << endl;
}