【算法】【题解】- POJ - 3278 Catch That Cow(BFS入门例题)

BFS入门例题

Catch That Cow

题目描述:
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.

思路

这道题中农夫和母牛在一条线上,让我们寻找农夫找到母牛的最短时间,即找到母牛的最短路径,因为每一种走法所耗费的时间都是一样的
我们有三种走法,可以后退一步,可以前进一步,可以直接到二倍于当前位置的点
按照这三种走法,暴力搜索即可,每走一步,只要不超过限制范围,就加入到队列里,只到最先找到了母牛,此时即找到了最短路径
需要注意的地方:
不可以重复的走已经走过的路,所以需要一个book数组(标记数组)来标记已经走过的路
每一次进入搜索后,需要对队列进行清零,因为上一次搜索时找到最短路径,队列里不一定为空
还有可能母牛在农夫的后面,三种走法中只有一种后退的走法,所以农夫只能一步步后退,找到母牛

AC代码
#include <queue>//队列所用的头文件
#include <cstdio>
#include <cstring>//memset函数在这个头文件里
#include <iostream>
using namespace std;
int n, k;//n是农夫的位置,k是母牛的位置
bool book[100005];//标记数组
struct node{//定义结构体
    int place, sum;//place是当前的位置,sum是花费的时间
};
queue<node> q;//定义队列q
node t, m, p;//t是模拟变量,m是起点,p是中间变量,用来存储当前队列最前面的值
void bfs(int n, int k)
{
    if(n >= k){ printf("%d\n",n - k); return;}//如果母牛在农夫后面,那么三种走法中农夫只能后退,每次后退一步,所以相差的距离即为所花费的分钟数
    q = queue<node>();//清空队列
    m.place = n;//起点坐标即农夫的初始位置
    m.sum = 0;//此时农夫还没有走,花费的时间为0
    q.push(m);//将起点压入队列
    memset(book,0,sizeof(book));//清空标记数组
    book[n] = 1;//起点标记为已经走过
    while(!q.empty()){//只要队列不空,就进行循环
        p = q.front();//p用来存储当前队列最前面的值
        q.pop();//将队列最前面的弹出
        t = p;//t来存储这个值,用来模拟
        t.place --;//如果后退一步
        if(t.place > 0 && book[t.place] == 0){//后退一步后如果满足条件,没有出这条线,并且这个位置没有走过,那么后退了一步
            t.sum ++;//后退一步,花费分钟数+1
            if(t.place == k){ printf("%d\n",t.sum); return;}//如果找到了母牛,输出花费的分钟数,bfs函数结束
            q.push(t);//在队列里压入这个位置
            book[t.place] = 1;//将这个位置标记已经走过
        }
        t = p;
        t.place ++;//如果前进一步
        if(t.place <= 100000 && book[t.place] == 0){//前进一步后如果满足条件,没有出这条线,并且这个位置没有走过,那么前进了一步
            t.sum ++;//前进一步,花费分钟数+1
            if(t.place == k){ printf("%d\n",t.sum); return;}//如果找到了母牛,输出花费的分钟数,bfs函数结束
            q.push(t);//在队列里压入这个位置
            book[t.place] = 1;//将这个位置标记已经走过
        }
        t = p;
        t.place *= 2;//如果传送到二倍于这个位置的位置
        if(t.place <= 100000 && book[t.place] == 0){//到这个位置后如果满足条件,没有出这条线,并且这个位置没有走过,那么就传送到了这个位置
            t.sum ++;//传送到这个位置,花费分钟数+1
            if(t.place == k){ printf("%d\n",t.sum); return;}//如果找到了母牛,输出花费的分钟数,bfs函数结束
            q.push(t);//在队列里压入这个位置
            book[t.place] = 1;//将这个位置标记已经走过
        }
    }

}
int main(void)
{
    while(~scanf("%d%d",&n,&k)){bfs(n, k);}//多次输入,进行搜索
    return 0;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值