请各位大佬有时间可以瞅一眼,剪枝策略大致没啥问题,使用一个一个空填的思路(而不是一行一行地填),95分。有一个点RE,本机能过。
代码:
#include<bits/stdc++.h>
using namespace std;
int mp[15][15],row[15][15],col[15][15],ar[15][15],nor[15],noc[15],noa[15],tot,ans;
struct blank {
int x,y,r,vx,vy,vr;
bool operator < (const blank &k) const {
if(vx != k.vx)
return vx < k.vx;
if(vy != k.vy)
return vy < k.vy;
if(vr != k.vr)
return vr < k.vr;
}
} bl[90];
const int val[90] = {
0,6,6,6,6,6,6,6,6,6,
6,7,7,7,7,7,7,7,6,
6,7,8,8,8,8,8,7,6,
6,7,8,9,9,9,8,7,6,
6,7,8,9,10,9,8,7,6,
6,7,8,9,9,9,8,7,6,
6,7,8,8,8,8,8,7,6,
6,7,7,7,7,7,7,7,6,
6,6,6,6,6,6,6,6,6
};
int cnt = 0;
void dfs(int m) {
cnt++;
if(m == tot + 1) {
int tmp = 0;
for(int i = 1; i <= 9; i++) {
for(int j = 1; j <= 9; j++) {
int pos = (i - 1) * 9 + j;
tmp += mp[i][j] * val[pos];
}
}
ans = max(ans,tmp);
return;
}
int mx = bl[m].x,my = bl[m].y,mr = bl[m].r;
for(int i = 1; i <= 9; i++) {
if(row[mx][i] || col[my][i] || ar[mr][i]) continue;
mp[mx][my] = i;
row[mx][i] = 1;
col[my][i] = 1;
ar[mr][i] = 1;
dfs(m + 1);
row[mx][i] = 0;
col[my][i] = 0;
ar[mr][i] = 0;
}
return;
}
int main() {
for(int i = 1; i <= 9; i++)
for(int j = 1; j <= 9; j++) {
scanf("%d",&mp[i][j]);
if(!mp[i][j]) {
nor[i]++;
noc[j]++;
bl[++tot].x = i;
bl[tot].y = j;
if(i <= 3) {
if(j <= 3)
bl[tot].r = 1;
else if(j <= 6)
bl[tot].r = 2;
else
bl[tot].r = 3;
} else if(i <= 6) {
if(j <= 3)
bl[tot].r = 4;
else if(j <= 6)
bl[tot].r = 5;
else
bl[tot].r = 6;
} else {
if(j <= 3)
bl[tot].r = 7;
else if(j <= 6)
bl[tot].r = 8;
else
bl[tot].r = 9;
}
noa[bl[tot].r]++;
} else {
int tmp;
if(i <= 3) {
if(j <= 3) tmp = 1;
else if(j <= 6) tmp = 2;
else tmp = 3;
} else if(i <= 6) {
if(j <= 3) tmp = 4;
else if(j <= 6) tmp = 5;
else tmp = 6;
} else {
if(j <= 3) tmp = 7;
else if(j <= 6) tmp = 8;
else tmp = 9;
}
row[i][mp[i][j]] = 1;
col[j][mp[i][j]] = 1;
ar[tmp][mp[i][j]] = 1;
}
}
for(int i = 1; i <= tot; i++) {
bl[i].vx = nor[bl[i].x];
bl[i].vy = noc[bl[i].y];
bl[i].vr = nor[bl[i].r];
}
sort(bl + 1,bl + tot + 1);
dfs(1);
if(ans == 0) {
printf("-1");
return 0;
}
printf("%d\n",ans);
return 0;
}