【SCOI2005】骑士精神

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

本题在BZOJ上的链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1085


 

QwQ,IDA*算法太好玩了!

在这里放一波我对迭代加深搜索、A*算法的理解(不一定对):

迭代加深搜索就是枚举DFS的最大深度,然后跑DFS,去验证不超过此深度的前提下是否有解;多用于答案上界很小或是搜索范围没有上界,其实就是防止了DFS一搜到底。

A*算法看起来像是一个剪枝,定义估价函数,乐观地估计从当前状态出发的最终解,若比当前已找到的解还要差,不用多说,剪掉!

迭代加深搜索又叫IDS,用在一起就叫IDA*了。。。

说说这道题,从看完课件里的分析到A掉没用多少时间,可能IDA*的做法比较固定。不过最可能的原因,就像课件里讲的,这类题最关键的就是找到估价函数。

估价函数找的时候往往需要转化一下,每次移动都会改变一个非空格子的状态,那么最少移动步数一定大于等于不相同格子的数目。一开始我只是单纯地扫了一下统计不同的个数,但忽略了一点,一次移动会使两个格子发生变化:初始的空格子和移动后的空格子。这样,并不是已移动的步数加上不相同格子的数目大于当前解就剪枝,而是将两数之和减1再比较。

 

 1 #include<cstdio>
 2 const int aim[6][6]={
 3     {0,0,0,0,0,0},
 4     {0,1,1,1,1,1},
 5     {0,0,1,1,1,1},
 6     {0,0,0,-1,1,1},
 7     {0,0,0,0,0,1},
 8     {0,0,0,0,0,0}
 9 };
10 const int mov[8][2]={{-2,-1},{-2,1},{2,-1},{2,1},{-1,-2},{1,-2},{-1,2},{1,2}};
11 int T,mt[6][6],ans,maxd;
12 void dfs(int d,int x,int y) {
13     if(d>maxd) return;
14     int flag=1,diff=0;
15     for(int i=1;i<=5;++i) {
16         for(int j=1;j<=5;++j)
17             if(mt[i][j]!=aim[i][j]) {flag=0;++diff;}
18     }
19     if(flag) {
20         if(d<ans) ans=d;
21         return;
22     }
23     if(d+diff-1>maxd) return;
24     for(int i=0;i<8;++i) {
25         int nx=x+mov[i][0],ny=y+mov[i][1];
26         if(nx<1||nx>5||ny<1||ny>5) continue;
27         mt[x][y]=mt[nx][ny];
28         mt[nx][ny]=-1;
29         dfs(d+1,nx,ny);
30         mt[nx][ny]=mt[x][y];
31         mt[x][y]=-1;
32     }
33 }
34 int main() {
35     scanf("%d",&T);
36     while(T--) {
37         int sx,sy;
38         char c;
39         for(int i=1;i<=5;++i)
40             for(int j=1;j<=5;++j) {
41                 while((c=getchar())=='\n'||c==' '||c=='\r');
42                 mt[i][j]=c=='*'?-1:c-'0';
43                 if(c=='*') sx=i,sy=j;
44             }
45         int flag=0;
46         ans=25;
47         for(maxd=0;maxd<=15;++maxd) {
48             dfs(0,sx,sy);
49             if(ans<=15) {printf("%d\n",ans);flag=1;break;}
50         }
51         if(!flag) printf("-1\n");
52     }
53     return 0;
54 }
AC代码

 

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