P1074 靶形数独
Posted olinr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1074 靶形数独相关的知识,希望对你有一定的参考价值。
题意:给你一个未完成的数独,每个位置上的价值等于数字乘上位置的价值(类似于打靶子)
https://www.luogu.org/problemnew/show/P1074#sub
要点 1.巧妙利用打表便于搜索与判断
2.贪心思想大量减少搜索的分支:每行(列)选0的个数少的填,减少了分支(不加此剪枝TLE一片。。。。。。)
1、刚开始别忘了加上初始的数的value
2、打表注意 0 0 都是 0,(因为打错表找了半天错。。。。QAQ)
#include<cstdio> #include<iostream> #include<cctype> #include<algorithm> using namespace std; #define love_nmr 0 int ans=-1; bool a[10][10]; bool b[10][10]; int value; struct node { int num; int id; friend bool operator < (const node &u,const node &v) { return u.num<v.num; } }tot[10]; struct spd { int x; int y; int gg; }s[105]; int cnt; int gong[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}}; int score[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}}; bool c[10][10]; int mp[10][10]; inline void dfs(int num,int val) { if(num>cnt) { ans=max(ans,val); return; } for(int i=1;i<=9;i++) { if(!a[s[num].x][i]&&!b[s[num].y][i]&&!c[s[num].gg][i]) { a[s[num].x][i]=true; b[s[num].y][i]=true; c[s[num].gg][i]=true; dfs(num+1,val+i*score[s[num].x][s[num].y]); a[s[num].x][i]=false; b[s[num].y][i]=false; c[s[num].gg][i]=false; } } } 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]) { a[i][mp[i][j]]=true; b[j][mp[i][j]]=true; c[gong[i][j]][mp[i][j]]=true; value+=mp[i][j]*score[i][j]; } else { tot[i].id=i; tot[i].num++; } } sort(tot+1,tot+10); for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) if(!mp[tot[i].id][j]) { s[++cnt].x=tot[i].id; s[cnt].y=j; s[cnt].gg=gong[tot[i].id][j]; } dfs(1,value); printf("%d",ans); return love_nmr; }
以上是关于P1074 靶形数独的主要内容,如果未能解决你的问题,请参考以下文章