POJ3278-Catch That Cow(BFS)
Catch That Cow
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 159649 Accepted: 48699
Description
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
xhk知道一头牛的位置,想要抓住它。xhk和牛都于数轴上 ,xhk起始位于点 N(0<=N<=100000) ,牛位于点 K(0<=K<=100000) 。xhk有两种移动方式:
1、从 X移动到 X-1或X+1 ,每次移动花费一分钟
2、从 X移动到 2*X ,每次移动花费一分钟
假设牛没有意识到xhk的行动,站在原地不。最少要花多少时间才能抓住牛?
Input
一行: 以空格分隔的两个字母: N 和 K
Output
一行: xhk抓住牛需要的最少时间,单位分
Sample Input
5 17
Sample Output
4
<WFU2019训练1>
这道题是POJ上的一道题,题目的意思是只有三种活动,即+1,-1,或者*2,求出从n到k变化的次数,我们用BFS的思路去解决问题,输入n,k,首先我们以n为中心,想外扩充3个数,即4,2,6,然后步数+1,再以这三个数为中心进行扩充,扩充一次步数+1,最后扩充到k的时候break,输出当前的步数即可。AC代码
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <cstring>
#include <utility>
using namespace std;
const int _max=1e6+5;
int book[_max];
int n,k,step;
typedef pair<int,int> p;
int main()
{
void bfs();
while(cin>>n>>k)
{
if(n==k)//特殊情况,n==k的时候要输出0,我因为这个点wa了一次
{
cout<<"0"<<endl;
continue;
}
step=0;
memset(book,0,sizeof(book));//每次book初始化为0
bfs();
cout<<step<<endl;
}
return 0;
}
void bfs()
{
queue<p>q;
p x(n,0);//定义一个pair x,存放当前的数和当前的步数,步数初始化为0
q.push(x);//第一个节点入队
book[n]=1;//book数组标记当前的数是否被扩充过
bool flag=false;//用来退出循环
int next[2]={1,-1};//扩充的方案
while(q.empty()!=1)
{
for(int i=0;i<3;i++)
{
if(i!=2)
x.first=q.front().first+next[i];
else
x.first=q.front().first*2;//第三种方案是*2
if(x.first<0||x.first>1000000)//注意数据范围是0-1e6
continue;
if(book[x.first]==0)
{
book[x.first]=1;//标记走过了
x.second=q.front().second+1;//步数是父亲节点+1
q.push(x);//符合条件 当前节点入队
}
if(x.first==k)
{
flag=true;
break;
}
}
if(flag)
break;
q.pop();
}
step=q.back().second;//步数给step
}