当前位置: 代码迷 >> 综合 >> POJ 3278 - Catch That Cow
  详细解决方案

POJ 3278 - Catch That Cow

热度:11   发布时间:2023-12-24 11:34:31.0

题目大意:一条x轴,一个人在n位置,牛在m位置,他要抓牛,牛不会动。他只会向前一步,向后一步或跨到当前坐标的两倍位置。问最少他要走几步。

解题思路:看着林炜代码,一行一行敲。。。首先,由于牛不会动,所以当用bfs中第一次碰到牛时,步数是最少的。解释如下:bfs中的循环,第一次是第一步能到的距离,第二次是第一步到的距离的第一个入队的第二步能到的距离,第三次是第一步到的距离的第二个入队的第二步能到的距离....以此类推。一个标记数组,初值为-1,非-1表示走过,不能再走(上面已经介绍第一次到达某位置,是步数最少的,所以不再走),标记数组也是计步数组,因为走过以后非-1,自然可以作为步数保存起来。循环之前,将人的位置的标记数组值赋为0,表示他不能会这个位置,因为这是浪费步数。将人的位置入队,这是人的第一步开始的地方。循环开始,将队列第一个出队传给变量,然后队列中删去(以后就走不到了),判断是否到达位置,到达则返回标记数组的值(步数),未到达则说明在牛之前,或牛之后,在牛之后,则只能一种操作后退,任何操作之前到要判断将移动的点是否走过,如果没走过进行操作,即记录步数,入队。

ac代码:

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
int n, k;
queue <int> qu;
int vis[200010];
int bfs()
{memset(vis, -1, sizeof(vis));int head=0, fail=0, p;while (!qu.empty())qu.pop();qu.push(n);vis[n] = 0;while (!qu.empty()){n = qu.front();qu.pop();if (n == k)return vis[n];if (n > k){p = n - 1;if (vis[p] == -1 && p >= 0){vis[p] = vis[n]+1;qu.push(p);			}}else {p = 2 * n;if (vis[p] == -1 && p < 200010){vis[p] = vis[n] + 1;qu.push(p);}p = n + 1;if (vis[p] == -1 && p <200010){vis[p] = vis[n] + 1;qu.push(p);}p = n - 1;if (vis[p] == -1 && p >= 0){vis[p] = vis[n] + 1;qu.push(p);} }}
}
int main()
{while (scanf("%d%d", &n, &k)!=EOF)printf("%d\n", bfs());
return 0;}