您的位置:首页 > 其它

Hrbust oj 1316 移动 II——BFS(广度优先搜索)

2018-02-21 14:40 295 查看
移动 II
Time Limit: 1000 MSMemory Limit: 65536 K
Total Submit: 487(147 users)Total Accepted: 219(137 users)Rating:





Special Judge: No
Description
在坐标轴[0,500]上存在两点A,B。
点A可以多次移动,每次移动需要遵循如下规则:
1.向后移动一步。
2.向前移动一步。
3.跳到当前坐标*2的位置上。

要求:利用宽搜算法编程求解从A移动到B的步数最少的方案,为使答案统一,要求搜索按照规则1、2、3的顺序进行。
Input
输入包含多组测试用例。
每组测试用例要求输入两个整数A,B。
Output
按要求输出步数最少的方案。
向后走输出"step back"。
向前走输出"step forward"。
跳跃输出"jump"。
对于每组结果需要追加一个空行。
Sample Input
5 17
5 18
3 499
Sample Output
step back
jump
jump
step forward

jump
step back
jump

step forward
jump
jump
jump
step back
jump
jump
step forward
jump
jump
step back
这题是一道很典型的BFS题型,也就是广度优先搜索,简称广搜。思路很简单,每一步都有三个选择,每个选择花费时间相同,所以我们就可以用广搜来完成这个操作。广度优先我就简单说一下
比如下面的这个图



我们要找从V0到V6的最短路径。BFS就是从V0开始有路就走,向外发散,直到找到终点V6为止。现在我们来演示一遍,V0有三个选择
第一步
①V0->V3
②V0->V1
③V0->V2
这时,从发散出去的三个点,我们还可以继续发散,注意,不能走回头路,所以在实现BFS的时候,走过的路要标记,让下一次发散不走回去。
第二步
①V3->V5
②V1->V4(其实V1还能走到V2,但是V2在第一步的时候已经走过,我们已经标记,走到V2的话还会比从V0到V2多一步,永远也比不了从V0直接到V2的速度,所以不走回头路)
③V2->V6 这时已经到达终点,所以显然,这是最短路。
这样大家就能理解什么叫广度优先搜索,以起点为中心,向外发散的,就叫广度优先搜索。
而广度优先搜索,他以队列为基础,因为队列只允许在表尾一端进行插入,在表头一端进行删除,所以我们就要有相关操作pop()出队列,push()压入队列,empty()检测队列是否为空,front()获取队列第一位的数据,end()获取尾部数据。
这道题,我们就有了一个思路,现在就需要代码实现了。
AC代码#include<stdio.h>
#include<string.h>
#include<cstdio>
#include<stdlib.h>
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
#define maxn 555
int step[maxn],pre[maxn],visit[maxn];
int bfs(int start,int endd)
{
memset(pre,-1,sizeof(pre)); ///记录每步位置之前的位置的数组,用BFS之前必须初始化。
memset(visit,0,sizeof(visit));///用来记录是否走了回头路的,我们在走过的路上都标记一遍。
queue<int> q; ///建立队列q
q.push(start);///起始位置压入队列
visit[start]=1;///起始位置标记为已走过,防止以后走回头路
while(!q.empty())///判断队列是否为空,若队列不为空,继续搜索
{
int fr=q.front(); //fr保存的是当前位置
q.pop(); ///第一位的元素出队列
if(fr==endd) return 1;///如果当前位置就是终点,结束搜索,最先搜索到的,就是最短路径
for(int i=1;i<=3;i++)///每步都有三种方法,前进,后退,jump,所以发散3次。
{
int j;
if(i==1)
{
j=fr-1;
}
if(i==2)
{
j=fr+1;
}
if(i==3)
{
j=fr*2;
}
if(j>=0&&j<=500&&visit[j]==0) ///如果不是回头路那就保存路径。
{
visit[j]=1; ///标记这个j点已经走过
pre[j]=fr;///记录路径
q.push(j);///把当前位置压入队列,继续往前发散。
}
}

}
return -1;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
memset(step,-1,sizeof(step));
int u=m;
int sum=0;
bfs(n,m);
while(pre[u]!=-1)
{
if(u==pre[u]-1)
{
step[sum++]=1;
}
else if(u==pre[u]+1)
{
step[sum++]=2;
}
else if(u==pre[u]*2)
{
step[sum++]=3;
}
u=pre[u];
}
for(int i=sum-1;i>=0;i--)
{
if(step[i]==1)
printf("step back\n");
else if(step[i]==2)
printf("step forward\n");
else printf("jump\n");
}
printf("\n");
}
}


其实BFS经典题型是走迷宫类型题,求最短路径的,在各大oj上都有很多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: