当青训营遇上码上掘金之”寻友之旅“

173 阅读2分钟

当青训营遇上码上掘金之”寻友之旅“

主题 3:寻友之旅

小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)

请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)

解题思路

主要使用了2个数组和1个队列来帮助解题:

1. dist数组
该数组长度与路径的最大结点数相同。数组中每个元素存储小青到该结点的最短时间。初始化时,将每个元素都赋予一个很大的值,以便计算过程中进行更新。

2. tag数组
该数组长度也与路径的最大结点数相同。数组中每个元素代表当前序号的结点是否已经过队列处理。初始化时,将每个元素赋值0,代表尚未处理该结点;待结点入队时,将值更新为1。

3. waiters队列
该队列用于存储待处理的结点。因采用广度优先搜索(BFS)的思想进行解题,故需要将当前搜索到的结点一一入队,而后再逐个出队进行接下来的搜索。搜索过程中,会对dist数组和tag数组中的值进行相应的更新。

源代码

#include <iostream>
#include <queue>
#include <cstring>

using namespace std;

int cal(int N, int K);

const int MAX = 1e5 + 1;

int main() {

    // 输入操作
    int N, K;
    cout << "请输入小青的位置:";
    cin >> N;
    cout << "请输入小码的位置:";
    cin >> K;

    cout << "小青到小码家所需的最短时间为:" << cal(N, K) << "分钟" << endl;

}

int cal(int N, int K) {
    if (N >= K) {
        return N - K;
    }
    else {
        // 初始化距离数组
        int dist[MAX];
        memset(dist, 0xf, sizeof(dist));
        dist[N] = 0;

        // 初始化标记结点数组,已处理记录为1,未处理记录为0
        int tag[MAX] = { 0 };
        tag[N] = 1;

        // 待处理结点的队列
        queue<int> waiters;

        // 将小青所在位置结点入队
        waiters.push(N);
        while (!waiters.empty()) {
            int num = waiters.front();
            waiters.pop();

            if (num + 1 < MAX) {
                dist[num + 1] = min(dist[num + 1], dist[num] + 1);
                if (!tag[num + 1]) {
                    waiters.push(num + 1);
                    tag[num + 1] = 1;
                }
            }
            if (num - 1 >= 0) {
                dist[num - 1] = min(dist[num - 1], dist[num] + 1);
                if (!tag[num - 1]) {
                    waiters.push(num - 1);
                    tag[num - 1] = 1;
                }
            }
            if (num * 2 < MAX) {
                dist[num * 2] = min(dist[num * 2], dist[num] + 1);
                if (!tag[num * 2]) {
                    waiters.push(num * 2);
                    tag[num * 2] = 1;
                }
            }
        }
        return dist[K];
    }
}

结果展示

微信图片编辑_20221221213540.jpg

微信图片编辑_20221221213655.jpg