https://loj.ac/problem/2591
题目描述
给出数独的一部分,并且每个位置的有一定分数,数独的总分数等于所有位置上的数值乘以其分数,求最大分数
思路
首先直接爆搜肯定会\(T\)掉,我们就需要贪心的从一种较优解开始搜索。我采用的是一种较优的方法,先统计一遍每行已知的个数,然后在将行排序一遍,从已知数字最多的那一行逐列搜索,全部搜索完后统计答案即可。注意维护数独的各个信息就可以了。
代码
#include <bits/stdc++.h> using namespace std; int mp[10][10]; bool l[10][10],h[10][10],jg[10][10]; int ans; int v[15][15]={{},{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}}; bool f; struct Node { int l,sum; }ll[20]; int cmp(Node a,Node b) { return a.sum<b.sum; } int change(int a,int b) { return (b-1)/3+(a-1)/3*3+1; } void dfs(int x,int y,int ha) { if(ha==10) { f=1; int sum=0; for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) sum+=mp[i][j]*v[i][j]; ans=max(ans,sum); return ; } if(y==10) { dfs(ll[ha+1].l,1,ha+1); return ; } if(!mp[x][y]) { for(int num=1;num<=9;num++) if(!h[x][num]&&!l[y][num]&&!jg[change(x,y)][num]) { mp[x][y]=num;h[x][num]=1;l[y][num]=1;jg[change(x,y)][num]=1; dfs(x,y+1,ha); mp[x][y]=0;h[x][num]=0;l[y][num]=0;jg[change(x,y)][num]=0; } } else dfs(x,y+1,ha); } int main() { for(int i=1;i<=9;i++) { int s=0; for(int j=1;j<=9;j++) { int a; scanf("%d",&a); if(!a)s++; mp[i][j]=a;h[i][a]=1;l[j][a]=1; jg[change(i,j)][a]=1; } ll[i].l=i;ll[i].sum=s; } sort(ll+1,ll+10,cmp); dfs(ll[1].l,1,1); if(f)printf("%d",ans); else printf("-1"); return 0; }