抓牛 (catchcow. cpp/c/pas)
题目描述
农夫约翰被通知, 他的一只奶牛逃逸了! 所以他决定, 马上出发, 尽快把那只奶牛抓回来.
他们都站在数轴上.约翰在 \(N (0 \leq N \leq 100000)\) 处, 奶牛在 \(K (0 \leq K \leq 100000)\) 处. 约翰有两种办法移动, 步行和瞬移: 步行每秒种可以让约翰从 x 处走到 x+l 或 x-l 处; 而瞬移则可让他在 1 秒内从 x 处消失, 在 2x 处出现.然而那只逃逸的奶牛, 悲剧地没有发现自己的处境多么糟糕, 正站在那儿一动不动.
那么, 约翰需要多少时间抓住那只牛呢?
输入格式
仅有两个整数 N 和 K
输出格式
最短时间
样例输入
5 17
样例输出
4
Explanation
暴力贪心不可取~
我不会告诉你这道题用 BFS / DFS 的.
Source Code
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <queue>
using namespace std;
const int maxn = 100100;
const int infinit = 0x0f7f7f7f;
int n, k;
int dp[maxn];
bool inque[maxn];
int bfs(void)
{
queue<int> que;
for (int i = 0; i <= max(n, k) + 10; i++)
dp[i] = infinit,
inque[i] = false;
que.push(n); inque[n] = true;
dp[n] = 0;
while (!que.empty()) {
int p = que.front();
que.pop();
// printf("deque %d -> %d\n", p, dp[p]);
if (p - 1 >= 0 && dp[p] + 1 < dp[p - 1]) {
dp[p - 1] = dp[p] + 1;
if (!inque[p - 1]) {
que.push(p - 1);
inque[p - 1] = true;
}
}
if (p + 1 <= max(n, k) + 10 && dp[p] + 1 < dp[p + 1]) {
dp[p + 1] = dp[p] + 1;
if (!inque[p + 1]) {
que.push(p + 1);
inque[p + 1] = true;
}
}
if (2 * p <= max(n, k) + 10 && dp[p] + 1 < dp[2 * p]) {
dp[2 * p] = dp[p] + 1;
if (!inque[2 * p]) {
que.push(2 * p);
inque[2 * p] = true;
}
}
inque[p] = false;
}
return dp[k];
}
int main(int argc, char** argv)
{
scanf("%d%d", &n, &k);
// I'm not using linear algorithm because it isn't correct. Use BFS instead.
printf("%d\n", bfs());
return 0;
}