农夫追牛问题
问题描述:
Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.
- Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute
- Teleporting: FJ can move from any point X to the point 2 × X in a single minute.
If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?
input:
Line 1: Two space-separated integers: N and K
output:
Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.
Sample Input:
5 17
Sample Output:
4
问题思路:
广度优先搜索,bfs,以农夫的行动分为三种状态。第一种,减一的操作,第二种加一的操作,第三种,乘二的操作。同时用一个bool型的数组来记录已经走过的位置。走过的位置不再去走。由于N,K均大于零,所以在进行加一,乘二的操作时,其,位置x必定是小于目标位置的。而,进行减一操作时,为了使减一操作有意义,其x必定大于等于一。即减一过后,必定大于等于零。其中设计了一个node的结构体,该结构体中,x,代表位置。step代表走过的步数。
代码如下
#include <iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
#define N 10000000
int start,aim;
//start初始位置,aim目标位置
struct node{
int x;
int step;
};
//记录两种状态
//1.该步所到达的位置
//2.走了多少步
bool vis[N];
//记录该点有没有被走过
queue<node> q;
void bfs()
{
while(!q.empty())
{
if(q.front().x==aim)
{
return;
}
node tmp;
int X=q.front().x;
int Step=q.front().step;
q.pop();
//进行减一的操作
if(X>=1&&!vis[X-1])
//要保证减1后有意义,所以要X >= 1
{
tmp.x=X-1;
tmp.step=Step+1;
vis[X-1]=1;
//记录已经到达过的位置
q.push(tmp);
}
//已经到达的位置不能重复到达
//进行加一的操作
if(X<aim&&!vis[X+1])
{
tmp.x=X+1;
tmp.step=Step+1;
vis[X+1]=1;
q.push(tmp);
}
//进行乘两倍的操作
if(X<aim&&!vis[2*X])
{
tmp.x=2*X;
tmp.step=Step+1;
vis[2*X]=1;
q.push(tmp);
}
}
}
int main()
{
while(cin>>start>>aim)
{
memset(vis,0,sizeof(vis));
while(!q.empty())q.pop();
//确保在进行操作之前队列为空
node ST;
ST.x=start;
ST.step=0;
q.push(ST);
//将根节点进队
//同时开始广度优先搜索
bfs();
cout<<q.front().step<<endl;
}
return 0;
}
//可以证明此处进队的可以是整个对象
注释:由于本人在跑这个题中出现了runtime error,以下是对runtime error的一些解释:
RuntimeError常见出错的原因可能有以下几种:
数组开得太小了,导致访问到了不该访问的内存区域
发生除零错误
大数组定义在函数内,导致程序栈区耗尽
指针用错了,导致访问到不该访问的内存区域
还有可能是程序抛出了未接收的异常