zoukankan      html  css  js  c++  java
  • 【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())=='
    '||c==' '||c=='
    ');
    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
    ",ans);flag=1;break;}
    50         }
    51         if(!flag) printf("-1
    ");
    52     }
    53     return 0;
    54 }
    AC代码
  • 相关阅读:
    多尺度双边滤波及基于小波变换的非线性扩散
    yum安装CentOS7+nginx+php7.3+mysql5.7
    python学习之特殊魔法__getattr__,__getattribute__
    python学习之特殊魔法__get__,__set__,__delete__
    python学习之装饰器
    python学习之私有属性
    python学习之包装与授权
    python学习之生成器(generator)
    python学习之运用特殊方法,定制类
    python学习之创建迭代器对象
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9715372.html
Copyright © 2011-2022 走看看