POJ 2243 Knight Moves(启发式搜索)

题目链接:http://poj.org/problem?id=2243

题目很简单,一般的BFS就能水过

一般的BFS可以直接用queue过掉,而且速度也很快,本题用启发式搜索效果不咋样,因为题目数据量不大

但是怎么能看出启发式搜索确实能提高效率呢,这样,按照两个反方向启发下,可以明显看出差别

把代码中重载的<里面>改成<一个跑45ms,一个跑200ms,一对比就出来了!

普通BFS

#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <queue>
using namespace std;
#define maxn 222222222
struct point{
    int x,y;
    int num;
    bool operator==(const point &a){
        return a.x==x && a.y==y;
    }
    point(int _x=0,int _y=0,int _num=0):x(_x),y(_y),num(_num){}
}begin,end;
char s[2],e[2];
int map[10][10];
int dir[8][2]={{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1}};
int ans=maxn;
queue<point> q;
int BFS(){
    point temp,now;
    q.push(begin);
    while(!q.empty()){
        temp=q.front(),q.pop();
        if(temp.num>=ans) continue;
        if(temp==end){
             ans=temp.num;
            // printf("ans:%d\n",ans);
        }
        for(int i=0;i<8;i++){
            now=point(temp.x+dir[i][0],temp.y+dir[i][1],temp.num+1);
            if(now.x<=0 || now.x>=9 || now.y>=9 || now.y<=0)
            continue;
            if(now.num<map[now.x][now.y]){
                map[now.x][now.y]=now.num;
                q.push(now);
            }
        }
    }
    return 0;
}
int main(){
    int i,j,k;
    while(scanf("%s%s",s,e)!=EOF){
        begin.x=s[1]-'0',begin.y=s[0]-'a'+1;
        end.x=e[1]-'0',end.y=e[0]-'a'+1;
        begin.num=0;
        //printf("%d %d %d %d\n",begin.x,begin.y,end.x,end.y);
        for(i=0;i<10;i++)
        for(j=0;j<10;j++)
        map[i][j]=maxn;
        //for(i=0;i<10;i++)map[i][0]=map[0][i]=map[9][i]=map[i][9]=0;
        map[begin.x][begin.y]=0;
        ans=maxn;
        BFS();
        printf("To get from %s to %s takes %d knight moves.\n",s,e,ans);
    }
    return 0;
}

启发式BFS

#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <queue>
#include <cmath>
using namespace std;
#define maxn 222222222
struct point{
    int x,y;
    int num;
    int va;
    bool operator==(const point &a){
        return a.x==x && a.y==y;
    }
    bool operator<(const point &a) const;
    point(int _x=0,int _y=0,int _num=0):x(_x),y(_y),num(_num){}
}begin,end;
bool point::operator<(const point &a) const{
    return va > a.va;
}
int get_h(point &a){
    return abs(a.x-end.x)+abs(a.y-end.y);
}
char s[2],e[2];
int map[10][10];
int dir[8][2]={{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1}};
int ans=maxn;
priority_queue<point> q;
int BFS(){
    point temp,now;
    q.push(begin);
    while(!q.empty()){
        temp=q.top(),q.pop();
        if(temp.num>=ans) continue;
        if(temp==end){
             ans=temp.num;
        }
        for(int i=0;i<8;i++){
            now=point(temp.x+dir[i][0],temp.y+dir[i][1],temp.num+1);
            if(now.x<=0 || now.x>=9 || now.y>=9 || now.y<=0)
            continue;
            if(now.num<map[now.x][now.y]){
                map[now.x][now.y]=now.num;
                now.va=get_h(now);
                q.push(now);
            }
        }
    }
    return 0;
}
int main(){
    int i,j,k;
    while(scanf("%s%s",s,e)!=EOF){
        begin.x=s[1]-'0',begin.y=s[0]-'a'+1;
        end.x=e[1]-'0',end.y=e[0]-'a'+1;
        begin.num=0;
        begin.va=get_h(begin);
        for(i=0;i<10;i++)
        for(j=0;j<10;j++)
        map[i][j]=maxn;
        map[begin.x][begin.y]=0;
        ans=maxn;
        BFS();
        printf("To get from %s to %s takes %d knight moves.\n",s,e,ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值