AcWing 1100 抓住那头牛【BFS 最短路径】

题目描述:

农夫知道一头牛的位置,想要抓住它。

农夫和牛都位于数轴上,农夫起始位于点 N,牛位于点 K。

农夫有两种移动方式:

1.从 X 移动到 X−1 或 X+1,每次移动花费一分钟
2.从 X 移动到 2∗X,每次移动花费一分钟
假设牛没有意识到农夫的行动,站在原地不动。

农夫最少要花多少时间才能抓住牛?

输入格式

共一行,包含两个整数N和K。

输出格式

输出一个整数,表示抓到牛所花费的最少时间。

数据范围

0≤N,K≤10^5

输入样例:

5 17

输出样例:

4

分析:这道题是一个一维的找最短路径的问题,题干很重要,无论+1,-1,* 2 花费都是1分钟,即权值相同, 所以才能用BFS去找最短路。
假设当前点为t , 目标点为k
出队扩展循环判断 1、如果t-1小于0了,那就不能走-1的方法 2、如果t+1 大于了N(10的5次方+10 ),就不能走+1的方法。 3、如果t * 2大于了N,也就不能走* 2的方法了。当然三个判断都应该加上此点是否被走过的条件,如果满足条件,就把其入队,出队时判断t是否等于k,如果相等就return距离。
那么为什么N要取的比K大一点呢,因为先减1再乘2扩大会比先乘再减一缩小更快的接近K,1、当k为偶数,假设为100,当前点为51,那么减一再乘更快,2、当k为奇数,假设为99,当前点为50,那么先乘再减一时更快一点的。所以N要取的比K大一点,当超过N的时候就不会有这样的区别,一定是先减再乘可以更快的接近K。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>

using namespace std;
const int N = 100010;

int n , k;
int dist[N];

int bfs(){
    memset(dist,-1,sizeof dist);
    queue<int> q;
    q.push(n);
    dist[n] = 0;
    
    while( q.size() )
    {
        int t = q.front();
        q.pop();
        
        if(t == k ) return dist[k]; 
         
        if( t - 1 >= 0 && dist[t-1] == -1)
        {
        	q.push(t-1);
        	dist[t-1] = dist[t] + 1;
		}
		if(t + 1 <= N && dist[t+1] == -1)
		{
			q.push(t+1);
			dist[t+1] = dist[t] + 1;
		}
        if( t * 2 <= N && dist[t*2] == -1)
        {
        	q.push(t*2);
        	dist[t*2] = dist[t] + 1;
		}
		
    }
}

int main(){
    scanf("%d%d",&n,&k);
    
    cout << bfs() << endl;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值