思路:把每个没有填的点按可填数字多少从小到大排序,依据排序后的顺序搜索。
卡不动了,求助qaq。
#include <bits/stdc++.h>
using namespace std;
int sc[10][10]={{0,0,0,0,0,0,0,0,0,0},
{0,6,6,6,6,6,6,6,6,6},
{0,6,7,7,7,7,7,7,7,6},
{0,6,7,8,8,8,8,8,7,6},
{0,6,7,8,9,9,9,8,7,6},
{0,6,7,8,9,10,9,8,7,6},
{0,6,7,8,9,9,9,8,7,6},
{0,6,7,8,8,8,8,8,7,6},
{0,6,7,7,7,7,7,7,7,6},
{0,6,6,6,6,6,6,6,6,6}};
int sg[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}};
struct node
{
int x,y,q;
}w[100];
int d[10][10],h[10][10],l[10][10],g[10][10],s[100],bh[10],bl[10],bg[10],p=0,cnt=0,ans=0;
bool cmp(struct node a,struct node b)
{
return a.q<b.q;
}
inline void dfs(int now,int sum)
{
int x=w[now].x,y=w[now].y;
if(now==cnt+1)
{
if(sum>ans)ans=sum;
return;
}
if(sum+(s[cnt]-s[now-1])*10<=ans)return;
for(register int i=1;i<=9;i++)
if(!h[x][i]&&!l[y][i]&&!g[sg[x][y]][i])
{
h[x][i]=l[y][i]=g[sg[x][y]][i]=1;
dfs(now+1,sum+sc[x][y]*i);
h[x][i]=l[y][i]=g[sg[x][y]][i]=0;
}
return;
}
int main()
{
for(register int i=1;i<=9;i++)
for(register int j=1;j<=9;j++)
{
scanf("%d",&d[i][j]);
if(d[i][j]!=0)h[i][d[i][j]]=1,l[j][d[i][j]]=1,g[sg[i][j]][d[i][j]]=1;
p+=d[i][j]*sc[i][j];
}
for(register int i=1;i<=9;i++)
for(register int j=1;j<=9;j++)
if(d[i][j]==0)++cnt,w[cnt].x=i,w[cnt].y=j,bh[i]++,bl[j]++,bg[sg[i][j]]++;
for(register int i=1;i<=cnt;i++)w[i].q=bh[w[i].x]+bl[w[i].x]+bg[sg[w[i].x][w[i].y]];
sort(w+1,w+cnt+1,cmp);
for(register int i=1;i<=cnt;i++)
s[i]=s[i-1]+sc[w[i].x][w[i].y];
dfs(1,0);
if(ans==0)printf("-1");
else printf("%d",ans+p);
return 0;
}