题目链接: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;
}