poj 3278 Catch That Cow

15 篇文章 0 订阅

更好的阅读体验

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

Hint
The fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.

【题意】
给你两个数字,你需要在有限步骤之内将第一个数字变成第二个数字,其中你可以进行三种操作:
1 将第一个数字进行加一。
2 将第一个数字进行减一。
3 将第一个数字翻倍。
问你最少要经过多少次能将第一个数字变成第二个数字。比如说测栗,5(翻倍)->10(减一)->9(翻倍)->18(减一)->17。一共四步,所以输出4。
用广搜可以做出来,每个状态最多有三个子状态,逐层搜索就行。

【代码】

#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;
struct P
{
    int a,b;
    P(int A=0,int B=0):a(A),b(B) {}
} p1(0,0);
bool vis[400005];//因为有×2操作可能会×爆,所以数组开大一点
int bfs(int a,int b)
{
    memset(vis,false,sizeof(vis));//每个数据都没有走过
    vis[a]=true;
    queue<P>ans;
    while(!ans.empty())
        ans.pop();//首先得清空队列
    p1.a=a,p1.b=0;
    ans.push(p1);
    while(!ans.empty())
    {
        p1=ans.front();
        ans.pop();
        if(p1.a==b)//如果找到答案了,就直接返回
            return p1.b;
        else if(p1.a<0)//小于0的肯定不是答案
            continue;
        else
        {
            if(!vis[p1.a+1]&&p1.a<=100000)//不能越界,并且没有搜索过这个数据
            {
                ans.push(P(p1.a+1,p1.b+1));
                vis[p1.a+1]=true;
            }
            if(!vis[p1.a-1]&&p1.a>=1)
            {
                ans.push(P(p1.a-1,p1.b+1));
                vis[p1.a-1]=true;
            }
            if(!vis[p1.a*2]&&p1.a*2<=100000)
            {
                ans.push(P(p1.a*2,p1.b+1));
                vis[p1.a*2]=true;
            }
        }
    }
}
int main()
{
    int a,b;
    scanf("%d%d",&a,&b);
    printf("%d\n",bfs(a,b));
    return 0;
}

【说明】这个代码只在poj上过了,别的oj好像过不了,不知道为啥,显示是wa,但是我感觉过程没问题。还有就是queue可以用数组来简化,因为队列比较慢,可以立两个flag来统计数组模拟queue,这题空间给的很小,不知道可不可行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zuhiul

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值