P1588 [USACO07OPEN] Catch That Cow S
题目描述
FJ 丢了一头牛,决定将其找回。FJ 和牛位于数轴上,初始位置分别为 x 和 y,牛保持不动。每次移动时,若 FJ 处于位置 p,他可移动至 p+1、p−1 或 2×p。计算 FJ 抓住牛所需的最少移动次数。
输入格式
第一行为一个整数 t (1≤t≤10),表示数据组数;
接下来每行包含一个两个正整数 x,y (0<x,y≤105),分别表示 FJ 和牛的坐标。
输出格式
对于每组数据,输出最少步数,每组数据间用换行隔开。
输入输出样例
输入 #1复制
1
5 17
输出 #1复制
4
这题用bfs。
cpp
#include<iostream>
#include<vector>
#include<queue>
#define int long long
using namespace std;
int n, k;
int ans = 0x3f3f3f3f;
const int N = 1e7;
vector<int>dis(N, 0x3f3f3f3f);
signed main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin >> n >> k;
dis[n] = 0;
queue<int>q;
q.push(n);
while (!q.empty())
{
int t = q.front();
q.pop();
if (dis[t] >= ans)
continue;
if (t == k)
{
ans = dis[t];
break;
}
if (t - 1 >= 0 && dis[t - 1] > dis[t] + 1)
{
q.push(t - 1);
dis[t - 1] = dis[t] + 1;
}
if (t + 1 <= N && dis[t + 1] > dis[t] + 1)
{
q.push(t + 1);
dis[t + 1] = dis[t] + 1;
}
if (t * 2 <=N && dis[t * 2] > dis[t] + 1)
{
q.push(t * 2);
dis[t * 2] = dis[t] + 1;
}
}
cout << ans;
return 0;
}
问题 B: 拯救行动
题目描述
公主被恶人抓走并关押在牢房的某个地方。牢房用 N×MN \times MN×M (N,M≤200)(N, M \le 200)(N,M≤200) 的矩阵表示。矩阵中的每项可以代表道路 @、墙壁 # 和守卫 x。
英勇的骑士决定孤身一人去拯救公主 a。假设拯救成功的表示是"骑士到达了公主所在的位置"。由于在通往公主所在位置的道路中可能遇到守卫,骑士一旦遇到守卫,必须杀死守卫才能继续前进。
先假设骑士可以向上、下、左、右四个方向移动,每移动一个位置需要 111 个单位时间,杀死一个守卫需要额外的 111 个单位时间。同时假设骑士足够强壮,有能力杀死所有的守卫。
给定牢房矩阵,公主、骑士和守卫在矩阵中的位置,计算拯救行动成功需要花费的最短时间。
输入
第一行为一个整数 SSS,表示输入的数据的组数(有多组输入)。
随后有 SSS 组数据,每组数据按如下格式输入:
- 两个整数,代表 NNN 和 MMM (N,M≤200)(N, M \le 200)(N,M≤200);
- 随后 NNN 行,每行有 MMM 个字符。
@代表道路,a代表公主,r代表骑士,x代表守卫,#代表墙壁。
输出
如果拯救行动成功,输出一个整数,表示行动的最短时间;如果不可能成功,输出 Impossible。
输入输出样例
样例输入 #1
复制
1
7 8
#@#####@
#@a#@@r@
#@@#x@@@
@@#@@#@#
#@@@##@@
@#@@@@@@
@@@@@@@@
样例输出 #1
复制
13