题目描述
FJ丢失了他的一头牛,他决定追回他的牛。已知FJ和牛在一条直线上,初始位置分别为x和y,假定牛在原地不动。FJ的行走方式很特别:他每一次可以前进一步、后退一步或者直接走到2*x的位置。计算他至少需要几步追上他的牛。
输入格式
一行: 以空格分隔的两个字母: N 和 K
输出格式
一行: 农夫抓住牛需要的最少时间,单位分钟
样例
样例输入 #1
1
5 17
样例输出 #1
4
解题思路
这也是一道bfs题。
一开始我一直在想如何限定不让农夫一直*2距离牛越来越远,这其实还是没有摆脱递归思想的束缚。
因为在广度搜索中,只要最短的情况搜出来了,其他的情况也就都不在进行下去了。这就引出了广度搜索的另一个好处,不需要设置什么min变量,因为第一个出来的结果就是最短的。
题解
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
int min, step;
//储存是否遍历过这个节点
bool vis[100001];
typedef struct nooo
{
int x;
int step;
} node;
int n, k;
queue<node> q;
int bfs()
{
node buf, next;
buf.x = n;
buf.step = 0;
q.push(buf);
while (!q.empty())
{
buf = q.front();
q.pop();
//三种走路的方式
for (int i = 0; i < 3; i++)
{
if (i == 0)
next.x = buf.x - 1;
else if (i == 1)
next.x = buf.x + 1;
else
next.x = buf.x * 2;
//越界了
if (next.x < 0 || next.x >= 100001)
continue;
if (!vis[next.x])
{
next.step = buf.step + 1;
q.push(next);
vis[next.x] = true;
}
if (next.x == k)
return next.step;
}
}
return 0;
}
int main()
{
scanf("%d %d", &n, &k);
memset(vis, false, sizeof(vis));
vis[n] = true;
//先清空队列(有些题是连续输入的)
while (!q.empty())
q.pop();
//要是在牛右边,肯定只能一步一步往回走
if (n >= k)
printf("%d\n", n - k);
else
printf("%d\n", bfs());
return 0;
}