当青训营遇上码上掘金
寻友之旅
题目描述
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K ,并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入格式:
两个整数 N 和 K
输出格式:
小青到小码家所需的最短时间(以分钟为单位)
数据范围
样例
输入样例:
5 17
输出样例:
4
本题其实就是Catch That Cow
解法:bfs求最短路 当所有边的权重为1时,可以使用bfs求最短路,有三种情况,每次将三种情况加入到队列中即可,加入之前需要判断一下是否越界与是否重复
一些可以优化的点:
- 零以后的点直接忽略即可,零之后的点除了+1均无法达到正数,而由+1重新回到正数的路径一定大于之前在相同点的距离
- 不难发现,如果一个数大于k,则只能选择从t走到t−1的方法。所以我们可以判断一下,t是否大于k。如果大于,则只执行从t走到t−1。当然,我们还可以在开始判断一下,如果是,则直接输出n−k
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
int st[N];
bool check(int now) {
if(now < 0 || now > 1e5 || st[now] != 0) return false;
return true;
}
int main() {
int n,k;
cin >> n >> k;
queue<int> q;
q.push(n);
int now = -1;
while(now != k) {
now = q.front();
q.pop();
if(check(now-1)) {
q.push(now-1);
st[now-1] = st[now] + 1;
}
if(check(now+1)) {
q.push(now+1);
st[now+1] = st[now] + 1;
}
if(check(now*2)) {
q.push(now*2);
st[now*2] = st[now] + 1;
}
}
cout << st[k] << endl;
return 0;
}