山再高,往上爬,总能登顶;
路再长,走下去,定能到达。
POJ-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?
输入
Line 1: Two space-separated integers: N and K
输出
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.
题目大意
你处于某一点,牛处于另一点,你可以直接跳跃到自己2*n的坐标上,也可以走到自己n+1的坐标和n-1的坐标上,问,你可以最少多少步能找到牛,牛的位置不动,这是一维的数轴。
题目解析
每一步都有三个选择,但是又不需要在一个方向上走的很久,只需解决当前即可,所以就有用bfs的思路了。
思路分析
其实思路很简单,但是有个坑点,就是限制条件。
首先你不能走到0之后,再然后你可以无穷的往前走,但是继续走下去会有很多没有意义的策略。因此你要删去这些不必要的麻烦。
不走到0之后这个很好解决,但是面对无穷大的范围不知道怎么划界限。
但是我们可以想到,一定不能是100000,因为有可能是翻倍之后往回走一点就走到了目标点,这样的解最优。但是,界限大于200000的话再往回走就不如直接走过去了,所以界限设成200000
OK有想法了就可以写代码了
注意的是,防止指针漂移,一定先判断限制条件,然后再进行操作。
其次,judge是否走过的地方尽量用数组,要开的大一些,满足要求即可,不要用map存储,可以用哈希存储,map走红黑树的话查询起来反倒不如哈希和直接用数组来的实在。
其次
在G++中可以用q.push(node{1,2})这种方式来直接入队列
AC时间到
#include<algorithm>
#include<iostream>
#include<string.h>
#include<utility>
#include<stdio.h>
#include<vector>
#include<string>
#include<math.h>
#include<cmath>
#include<queue>
#include<stack>
#include<deque>
#include<map>
#pragma warning(disable:4244)
#define PI 3.1415926536
#pragma GCC optimize(2)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll ll_inf = 9223372036854775807;
const int int_inf = 2147483647;
const short short_inf = 32767;
const char char_inf = 127;
ll GCD(ll a, ll b) { return a ? GCD(b, a % b) : a; }
inline ll read() {
ll c = getchar(), Nig = 1, x = 0;
while (!isdigit(c) && c != '-')c = getchar();
if (c == '-')Nig = -1, c = getchar();
while (isdigit(c))x = ((x << 1) + (x << 3)) + (c ^ '0'), c = getchar();
return Nig * x;
}
inline void out(ll a)
{
if (a < 0)putchar('-'), a = -a;
if (a >= 10)out(a / 10);
putchar(a % 10 + '0');
}
ll qpow(ll x, ll n, ll mod) {
ll res = 1;
while (n > 0) {
if (n & 1)res = (res * x) % mod;
x = (x * x) % mod; n >>= 1;
}
return res;
}
#define read read()
bool judge[200007];
struct node {
int x, step;
};
queue<node>q;
node temp;
void bfs(int End) {
while (!q.empty()) {
temp = q.front();
q.pop();
if (temp.x == End) {
cout << temp.step << endl;
return;
}
if ((temp.x * 2 <= 200000) && (!judge[temp.x * 2])) {////先判断条件
judge[temp.x * 2] = true;
q.push(node{ temp.x * 2,temp.step + 1 });
}
if ((temp.x + 1 <= 200000) && (!judge[temp.x + 1])) {////先判断条件
judge[temp.x + 1] = true;
q.push(node{ temp.x + 1,temp.step + 1 });
}
if ((temp.x >= 1) && (!judge[temp.x - 1])) {//先判断条件
judge[temp.x - 1] = true;
q.push(node{ temp.x - 1,temp.step + 1 });
}
}
}
int main() {
int Sta = read, End = read;
if (Sta >= End) {//因为反向走的方法只有一种,直接出结果就可以了
cout << Sta - End << endl;
return 0;
}
q.push(node{ Sta,0 });
judge[Sta] = true;
bfs(End);
}
By-轮月