poj3278——Catch That Cow(BFS,剪枝)

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

n只有三种变换情况,+1,-1,x2,求n最少能经过多少步成为k。
乍看很简单,对三种情况BFS就行了,但这个数据很大,容易TLE或者RE。
我第一次TLE,之后就设置了一个观察数组,如果某次BFS时又碰到了这个数,这时的次数肯定不是最小的。
第二次RE,又考虑了n大于k的情况,这时候肯定只能一直-1,所以特判。又x2的操作容易超数组,所以如果某次x2超过了目标的两倍,那肯定是没用的,剪掉。到达负数也不行,剪掉。最后就过了

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <set>
#include <vector>
#include <iomanip>
#include <stack>
#include <map>
#include <queue>
#define MAXN 100010
#define mod 100010
#define INF 0x3f3f3f3f
using namespace std;
int n,k,ans;
int vis[MAXN*10];
struct Node
{
    int num;
    int step;
};
void bfs(int n)
{
    queue<Node> q;
    Node start,tmp1,tmp2;
    start.num=n;
    start.step=0;
    q.push(start);
    while(!q.empty())
    {
        tmp1=q.front();
        q.pop();
        if(tmp1.num==k)
        {
            ans=min(ans,tmp1.step);
            return;
        }
        if(tmp1.num-1>=0)
        {
            tmp2.num=tmp1.num-1;
            tmp2.step=tmp1.step+1;
            if(!vis[tmp2.num])
            {
                vis[tmp2.num]=1;
                q.push(tmp2);
            }
        }
        tmp2.num=tmp1.num+1;
        tmp2.step=tmp1.step+1;
        if(!vis[tmp2.num])
        {
            vis[tmp2.num]=1;
            q.push(tmp2);
        }
        if(tmp1.num*2<k*2)
        {
            tmp2.num=tmp1.num*2;
            tmp2.step=tmp1.step+1;
            if(!vis[tmp2.num])
            {
                vis[tmp2.num]=1;
                q.push(tmp2);
            }
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    while(cin>>n>>k)
    {
        ans=INF;
        if(n>=k)
        {
            cout<<n-k<<endl;
            continue;
        }
        memset(vis,0,sizeof(vis));
        bfs(n);
        cout<<ans<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值