• Luogo P2324 [SCOI2005]骑士精神


      所有想练习A*的人都先来敲一下这道题吧。

      数据范围即便只有5*5,但朴素的爆搜还是会超时。

      因此考虑剪枝。

      对于这道题,肯定只要进行最优化剪枝,判断现在走的步数+剩下最少要走的步数,如果大于ans或者15就return;

      那么,估价函数怎么写?

      利用小学生的思想,将目前的图与目标状态对比一下,还有多少棋子没有归位,那么至少就要走几步(每次最多归位一个)

      还有一个技巧:存储空格的位置,这样可以简化搜索。

      CODE

    #include<cstdio>
    #include<iostream>
    using namespace std;
    const int g[6][6]=
    {
        {0,0,0,0,0,0},
        {0,2,2,2,2,2},
        {0,1,2,2,2,2},
        {0,1,1,0,2,2},
        {0,1,1,1,1,2},
        {0,1,1,1,1,1},
    };
    const int fx[8]={1,1,-1,-1,2,2,-2,-2},fy[8]={2,-2,2,-2,1,-1,1,-1};
    int t,a[6][6],ans,i,j,x,y;
    char ch;
    inline int h()
    {
        int tot=0;
        for (int i=1;i<=5;++i)
        for (int j=1;j<=5;++j)
        if (a[i][j]!=g[i][j]) ++tot;
        return tot;
    }
    inline void Astar(int k,int x,int y)
    {
        if (!h()) ans=k<ans?k:ans;
        if (k+h()>ans) return; 
        for (int i=0;i<8;++i)
        {
            int xx=fx[i]+x,yy=fy[i]+y;
            if (xx>0&&yy>0&&xx<=5&&yy<=5)
            {
                swap(a[x][y],a[xx][yy]);
                Astar(k+1,xx,yy);
                swap(a[x][y],a[xx][yy]);
            }
        }
    }
    int main()
    {
        scanf("%d",&t);
        while (t--)
        {
            for (i=1;i<=5;++i)
            {
                for (j=1;j<=5;++j)
                {
                    cin>>ch;
                    if (ch=='0') a[i][j]=1; else if (ch=='1') a[i][j]=2; else x=i,y=j,a[i][j]=0;
                }
            }
            ans=16;
            Astar(0,x,y);
            if (ans>15) puts("-1"); else printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    23.课程应用接口
    22.课程页面设计
    21.手机接口
    20.云通讯
    19.JWT
    18.权限认证
    解决github下载慢的终极方法
    vs code 配置c/c++环境
    Python 字符编码处理总结
    Python编码
  • 原文地址:https://www.cnblogs.com/cjjsb/p/8278789.html
Copyright © 2020-2023  润新知