POJ 3278 HDU 2717 Catch That Cow

来源:互联网 发布:cad专业绘图软件 编辑:程序博客网 时间:2024/05/23 22:18

Problem Description

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.

    这道题是典型的宽搜BFS,题意大概是Farmer John要抓奶牛。
    Farmer John只有一下三种移动方式:
        

  1. 向前走一步,耗时一分钟。
  2. 向后走一步,耗时一分钟。
  3. 向前移动到当前位置的两倍N*2,耗时一分钟。

     奶牛是不会动的。

通过分析可知,当奶牛在Farmer John后面时(即n >= k),Farmer John只能一步一步往回走,此时步数step = n - k.

其他情况则通过宽搜求结果。

根据宽搜的性质,所求得的结果必然是最优解。

代码如下:

#include<cstdio>#include<queue>#include<cstring>const int MAX = 100000 + 5;int n = 0, k = 0;int step[MAX];bool book[MAX];bool ok(int x)//检查是否越界{    if (x < 0 || x > MAX - 5)        return false;    return true;}void check(int next, int last, std::queue<int>&q)//模拟走路的方式{    if (ok(next) && !book[next]) {        step[next] = step[last] + 1;        q.push(next);        book[next] = true;    }}void BFS(){    int last = 0, next = 0;    std::queue<int> q;    book[n] = true;    step[n] = 0;    q.push(n);    while (!q.empty()) {        last = q.front();        q.pop();        if (last == k) printf("%d\n", step[last]);        next = last - 1;        check(next, last, q);        next = last + 1;        check(next, last, q);        next = last * 2;        check(next, last, q);    }}int main(){    while (scanf("%d%d", &n, &k) == 2) {        memset(book, false, sizeof book);        memset(step, 0, sizeof book);        if (k <= n) printf("%d\n", n - k);        else BFS();    }    return 0;}

刚开始时,在ok函数中,我写成if (x < 0 || x >= MAX - 5) 结果wrong answer 了。尴尬。被边界数据阴了。。。。。所以是不需要等号的。因为测试的数据中最大刚好有个100000。