poj 2243(A*搜索orBFS)

Knight Moves

以前听说过A*搜索这个推崇备至的算法,但没有去认真阅读过相关资料,今天(2013/10/0D)认真学习了一下

通过这题学习了A*搜索,下面就来描述一下A*搜索的详细过程:

   1,把起始格添加到开启列表。
   2,重复如下的工作:
      a) 寻找开启列表中F值最低的格子。我们称它为当前格。
      b) 把它切换到关闭列表。
      c) 对相邻的格中的每一个?
          * 如果它不可通过或者已经在关闭列表中,略过它。反之如下。
          * 如果它不在开启列表中,把它添加进去。把当前格作为这一格的父节点。记录这一格的F,G,和H值。
          * 如果它已经在开启列表中,用G值为参考检查新的路径是否更好。更低的G值意味着更好的路径。如果是这样,就把这一格的父节点改成当前格,并且重新计算这一格的G和F值。如果你保持你的开启列表按F值排序,改变之后你可能需要重新对开启列表排序。
      d) 停止,当你
          * 把目标格添加进了关闭列表(注解),这时候路径被找到,或者
          * 没有找到目标格,开启列表已经空了。这时候,路径不存在。
   3.保存路径。从目标格开始,沿着每一格的父节点移动直到回到起始格。这就是你的路径。

下面就来做题巩固一下:
poj  2243  Knight Moves

题目的意思大概是说:在国际象棋的棋盘上,一匹马共有8个可能的跳跃方向,求从起点到目标点之间的最少跳跃次数。

内存:176K      耗时 :  32MS  (将队列定义为全局,可减少时间)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
using namespace std;

struct knight{
    int x,y,step;
    int f,g,h;//启发:f=g+h;
    bool operator <(const knight& a)const{
      return  f>a.f;//重载<,每次选择代价最小的
    }
    bool operator ==(const knight& a)
    {
        return (x==a.x&&y==a.y)?1:0;
    }
    bool ok()
    {
        if(x>=0&&x<8&&y>=0&&y<8)
            return 1;
        else
            return 0;
    }
}s,e;
bool vis[8][8];//已访问列表
int dir[8][2]={{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2}};
priority_queue<knight>Q;//定义为全局可减少时间
int Heuristic(const knight& a)
{   //用曼哈顿距离作为估值函数
    return (abs(a.x-e.x)+abs(a.y-e.y))*10;//距离扩大10倍
}
int Astar()
{
    memset(vis,0,sizeof(vis));
    while(!Q.empty())
        Q.pop();
    Q.push(s);
    vis[s.x][s.y]=1;
    if(s==e)return 0;
    knight pre,now;
    while(!Q.empty())
    {
        pre=Q.top();
        Q.pop();
        for(int i=0;i<8;i++)
        {
            now.x=pre.x+dir[i][0];
            now.y=pre.y+dir[i][1];
            now.step=pre.step+1;
            if(now.ok()&&!vis[now.x][now.y])
            {
                if(now==e) return now.step;
                now.g=pre.g+22;//这里为√5*10
                now.h=Heuristic(now);
                now.f=now.g+now.h;
                Q.push(now);
                vis[now.x][now.y]=1;//标记该点已访问
            }
        }
    }
    return -1;
}

int main()
{
    char s1[3],s2[3];
    while(~scanf("%s%s",s1,s2))
    {
        s.x=s1[0]-'a';s.y=s1[1]-'1';
        s.f=s.g=s.h=s.step=0;
        e.x=s2[0]-'a';
        e.y=s2[1]-'1';
        int ans=Astar();
        printf("To get from %s to %s takes %d knight moves.\n",s1,s2,ans);
    }
    return 0;
}

之后,我又用BFS做了一下:(从这个题看不出什么差距,可能数据量不大)
Accepted   176K  耗时: 16MS

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
int step[8][8];
struct node
{
    int x,y;
};
int dir[8][2]={{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2}};
queue <node> q;
int BFS(node begin,node end)
{
    memset(step,0,sizeof(step));
    while(!q.empty())
      q.pop();
    node temp,next;
    q.push(begin);
    while(!q.empty())
    {
        temp=q.front();
        q.pop();
        for(int i=0;i<8;i++)
        {
            next.x=temp.x+dir[i][0];
            next.y=temp.y+dir[i][1];
            if(next.x<0||next.x>=8||next.y<0||next.y>=8)
                continue;
            if(step[next.x][next.y]>0)
                continue;
            step[next.x][next.y]=step[temp.x][temp.y]+1;
            q.push(next);
            if(next.x==end.x && next.y==end.y)
                return step[next.x][next.y];
        }
    }
    return -1;
}
int main ()
{
    char s1[3],s2[3];
    node begin,end;
    while(scanf("%s%s",s1,s2)!=EOF)
    {
        if(strcmp(s1,s2)==0)
        {
            printf("To get from %s to %s takes 0 knight moves.\n",s1,s2);
            continue;
        }
        begin.x=s1[1]-'1';begin.y=s1[0]-'a';
        end.x=s2[1]-'1';end.y=s2[0]-'a';
        printf("To get from %s to %s takes %d knight moves.\n",s1,s2,BFS(begin,end));
    }
    return 0;
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值