zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    解决docker pull很慢的方法
    Linux 基础 Day1
    linux运维人员必须熟悉的运维工具汇总
    chrome 浏览器插件推荐
    只能运维主要职责
    Linux查看所有用户用命令
    ubuntu16.04 离线包安装docker
    2013-10
    ELK原理与介绍
    shell中各种括号的作用()、(())、[]、[[]]、{}
  • 原文地址:https://www.cnblogs.com/cjjsb/p/8278789.html
Copyright © 2011-2022 走看看