抓住那头牛(POJ NO.2971)

    科技2022-07-11  101

    问题描述

    农夫知道一头牛的位置,想要抓住它。农夫和牛都位于数轴上,农夫起始位于点N(0<=N<=100000),牛位于点K(0<=K<=100000)。农夫有两种移动方式:

    从X移动到X-1或X+1,每次移动花费一分钟从X移动到2*X,每次移动花费一分钟

    假设牛没有意识到农夫的行动,站在原地不动。农夫最少要花多少时间才能抓住牛?

    输入 两个整数,N和K

    输出 一个整数,农夫抓到牛所要花费的最小分钟数

     

    样例

    INPUT

    5 17

     

    OUTPUT

    4

     

    解题思路

    BFS

    dfs主要用于整个图的遍历,可以求得多个解;bfs则常用于求最短路径如本题。本题的移动方法有三种:向后一步、向前一步和传送(位置*2),则用队列存储每次行动这三种移动方法的结果,每次行动让时间+1。

     

    完整代码

    #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <stack> #include <vector> #include <iomanip> #include <queue> using namespace std; struct point{//位置和所用时间 int x; int time; }; queue <point> Q; int n, k, flag[100001];//flag用于标记若曾走过则不再查询 void bfs(){ while(!Q.empty()){ point t = Q.front();//读取初始的位置t.x和所用时间t.time = 0 Q.pop(); int X = t.x; int Time = t.time;//在循环中每次保存弹出的位置和时间 if(X == k){//找到牛 cout<<Time<<endl; return; } //没找到,有三种走法,左走一步、右走一步和传送,分别分析 if(X >= 1&&!flag[X - 1]){ flag[X - 1] = 1; point tem; tem.x = X - 1; tem.time = Time + 1; Q.push(tem);//将此种走法(位置和用时)存入队列 } if(X <= k&&!flag[X + 1]){ flag[X + 1] = 1; point tem; tem.x = X + 1; tem.time = Time + 1; Q.push(tem); } if(X <= k&&2*X <= 100001&&!flag[2*X]){ flag[2*X] = 1; point tem; tem.x = 2*X; tem.time = Time + 1; Q.push(tem); } } } int main(){ cin>>n>>k; point t; t.x = n; t.time = 0; Q.push(t); bfs(); return 0; }

    参考链接:https://blog.csdn.net/qq_43746332/article/details/89930172

    Processed: 0.040, SQL: 8