【NOIP2009】靶形数独

本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P1074


 

一道学习搜索的好题!

看到一位老师的课件里写着,单纯搜索是过不了的(废话),需要优化!优化1:最优性优化;优化2:搜索顺序优化。

我想了想,从易到难吧。先写个裸的搜索,确实没过。优化1写起来没啥思路,想不到简单易行的,先写2吧,结果过了。再去写写1吧,超。。时了?

一定是我的代码不优美,怎么样求接下来最优的解不会超过多少呢?网上也没有什么好的做法。而且大家一致说,只优化顺序就OK了,甚至直接倒着搜就能过。

真是没啥好说的了。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 int mt[10][10],ans=-1,line[10][10],range[10][10],small[10][10],score[10][10],which[10][10];
 5 inline int max(int a,int b) {return a>b?a:b;}
 6 inline int gs(int x,int y) {
 7     return (x-1)/3*3+(y-1)/3+1;
 8 }
 9 inline int gd(int x,int y) {
10     if(x>5) x=10-x;
11     if(y>5) y=10-y;
12     if(y<x) x=y;
13     return x+5;
14 }
15 struct ln {
16     int n,num;
17     bool operator < (const ln& rhs) const {
18         return num>rhs.num;
19     }
20 } L[10];
21 void dfs(int tx,int y,int now) {
22     if(tx==10) {ans=max(ans,now);return;}
23     if(y==10) {dfs(tx+1,1,now);return;}
24     int x=L[tx].n;
25     if(mt[x][y]) dfs(tx,y+1,now+mt[x][y]*score[x][y]);
26     else for(int i=1;i<=9;++i)
27         if(!line[x][i]&&!range[y][i]&&!small[which[x][y]][i]) {
28             mt[x][y]=i;
29             line[x][i]=range[y][i]=small[which[x][y]][i]=1;
30             dfs(tx,y+1,now+mt[x][y]*score[x][y]);
31             mt[x][y]=0;
32             line[x][i]=range[y][i]=small[which[x][y]][i]=0;
33         }
34 }
35 int main() {
36     for(int i=1;i<=9;++i) L[i].n=i,L[i].num=0;
37     for(int i=1;i<=9;++i)
38         for(int j=1;j<=9;++j) {
39             scanf("%d",&mt[i][j]);
40             line[i][mt[i][j]]=range[j][mt[i][j]]=small[gs(i,j)][mt[i][j]]=1;
41             score[i][j]=gd(i,j);
42             which[i][j]=gs(i,j);
43             if(mt[i][j]) ++L[i].num;
44         }
45     sort(L+1,L+10);
46     dfs(1,1,0);
47     printf("%d",ans);
48     return 0;
49 }
AC代码

 

posted @ 2018-09-25 20:04  Mr^Kevin  阅读(176)  评论(0编辑  收藏  举报