1.用dt[]存待填的位置,保存行列宫每个数字的状态。
2.为防止TLE,我们可以从0最少的行开始搜。
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 12;
struct node {
int id, num;
bool operator < (const node& a) {
return num < a.num;
}
}cnt_0[maxn]; //每行0的数量
int cnt, ans, maxx;
int map[maxn][maxn], dt[maxn * maxn][3];
// 存初始 待填的位置
bool hang[maxn][maxn], lie[maxn][maxn], gong[maxn][maxn];
// 标记是否用过
//返回宫
int get_gong(int x, int y)
{
return (x - 1) / 3 * 3 + (y - 1) / 3 + 1;
}
//分数
int score(int x, int y)
{
if (x == 1 || x == 9 || y == 1 || y == 9) return 6;
if (x == 2 || x == 8 || y == 2 || y == 8) return 7;
if (x == 3 || x == 7 || y == 3 || y == 7) return 8;
if (x == 4 || x == 6 || y == 4 || y == 6) return 9;
return 10;
}
void dfs(int u, int tot)
{
//填完更新答案返回
if (u == cnt) {
maxx = max(maxx, tot);
return;
}
for (int i = 1; i <= 9; i++) {
//判断i是否可填
if (!hang[dt[u][0]][i] && !lie[dt[u][1]][i] && !gong[dt[u][2]][i]) {
hang[dt[u][0]][i] = 1;
lie[dt[u][1]][i] = 1;
gong[dt[u][2]][i] = 1;
dfs(u + 1, tot + i * score(dt[u][0], dt[u][1]));
hang[dt[u][0]][i] = 0;
lie[dt[u][1]][i] = 0;
gong[dt[u][2]][i] = 0;
}
}
}
int main(void)
{
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= 9; j++) {
cin >> map[i][j];
if (!map[i][j]) {
cnt_0[i].id = i;
cnt_0[i].num++; //i行0的数量
}
else {
hang[i][map[i][j]] = 1;
lie[j][map[i][j]] = 1;
gong[get_gong(i, j)][map[i][j]] = 1;
ans += map[i][j] * score(i, j);
}
}
}
sort(cnt_0 + 1, cnt_0 + 10); //按0的数量排序
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= 9; j++) {
//保存待填的位置
if (!map[cnt_0[i].id][j]) {
dt[cnt][0] = cnt_0[i].id;
dt[cnt][1] = j;
dt[cnt++][2] = get_gong(cnt_0[i].id, j);
}
}
}
dfs(0, 0);
if (!maxx) cout << "-1" << endl; //无解
else cout << ans + maxx << endl;
return 0;
}