B. Frog Traveler

目录

1.Problem

2.Input

3.Output

4.Examples

4.1input

4.2output

5.Code

6.Conclusion


1.Problem

Frog Gorf is traveling through Swamp kingdom. Unfortunately, after a poor jump, he fell into a well of nn meters depth. Now Gorf is on the bottom of the well and has a long way up.

The surface of the well's walls vary in quality: somewhere they are slippery, but somewhere have convenient ledges. In other words, if Gorf is on xx meters below ground level, then in one jump he can go up on any integer distance from 00 to axax meters inclusive. (Note that Gorf can't jump down, only up).

Unfortunately, Gorf has to take a break after each jump (including jump on 00 meters). And after jumping up to position xx meters below ground level, he'll slip exactly bxbx meters down while resting.

Calculate the minimum number of jumps Gorf needs to reach ground level.

2.Input

The first line contains a single integer nn (1≤n≤3000001≤n≤300000) — the depth of the well.

The second line contains nn integers a1,a2,…,ana1,a2,…,an (0≤ai≤i0≤ai≤i), where aiai is the maximum height Gorf can jump from ii meters below ground level.

The third line contains nn integers b1,b2,…,bnb1,b2,…,bn (0≤bi≤n−i0≤bi≤n−i), where bibi is the distance Gorf will slip down if he takes a break on ii meters below ground level.

3.Output

If Gorf can't reach ground level, print −1−1. Otherwise, firstly print integer kk — the minimum possible number of jumps.

Then print the sequence d1,d2,…,dkd1,d2,…,dk where djdj is the depth Gorf'll reach after the jj-th jump, but before he'll slip down during the break. Ground level is equal to 00.

If there are multiple answers, print any of them.

4.Examples

4.1input

3
0 2 2
1 1 0

4.2output

2
1 0 

5.Code

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int MAXN = 3e5 + 5;
const int MAXM = 1e6 + 5;

int n;
vector<int> a(MAXN), b(MAXN);
vector<int> dis(2 * MAXN, 1 << 30), fr(2 * MAXN);
vector<int> v(MAXM), c(MAXM), nxt(MAXM), h(2 * MAXN);

void addedge(int x, int y, int z) {
    static int tot = 0;
    v[++tot] = y;
    nxt[tot] = h[x];
    h[x] = tot;
    c[tot] = z;
}

void bfs(int s) {
    dis[s] = 0;
    fr[s] = -1;
    queue<int> q1, q2;
    q1.push(s);
    
    while (!q1.empty() || !q2.empty()) {
        int t;
        if (!q2.empty()) {
            t = q2.front();
            q2.pop();
        }
        else {
            t = q1.front();
            q1.pop();
        }
        
        for (int p = h[t]; p; p = nxt[p]) {
            if (dis[v[p]] > dis[t] + c[p]) {
                dis[v[p]] = dis[t] + c[p];
                fr[v[p]] = t;
                
                if (!c[p]) {
                    q2.push(v[p]);
                }
                else {
                    q1.push(v[p]);
                }
            }
        }
    }
}

void work(int u) {
    if (fr[u] >= 0) {
        work(fr[u]);
    }
    
    if (!u) {
        printf("0 ");
    }
    else if (fr[u] > n && u <= n) {
        printf("%d ", fr[u] - n);
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    
    for (int i = 1; i <= n; i++) {
        cin >> b[i];
    }
    
    for (int i = 1; i <= n; i++) {
        if (a[i] == i) {
            addedge(i, 0, 1);
            continue;
        }
        addedge(i, i - a[i] + n, 1);
    }
    
    for (int i = 1; i < n; i++) {
        addedge(i + n, i + n + 1, 0);
    }
    
    for (int i = 1; i <= n; i++) {
        addedge(i + n, i + b[i], 0);
    }
    
    bfs(n);
    
    if (dis[0] == (1 << 30)) {
        printf("-1\n");
    }
    else {
        printf("%d\n", dis[0]);
        work(0);
        printf("\n");
    }
    
    return 0;
}

6.Conclusion

上面的代码是一个解决问题的算法实现。下面我将逐个解释其功能:

1.首先,代码包含了一些必要的头文件,其中&lt;bits/stdc++.h&gt;是包含了所有STL的头文件,使得可以直接使用STL中的数据结构和算法。
2.接着定义了一些常量和变量,包括数组和向量。这些数据结构用于存储输入和算法过程中的中间结果。
3.addedge函数用于向图中添加边。它接受三个参数,起点、终点和边的权重。通过维护一个邻接链表来表示图的结构。
4.bfs函数实现了广度优先搜索算法,用于计算最短路径。它接受一个起始节点作为参数,并使用队列来遍历图,更新节点的最短距离和最短路径。
5.work函数是一个递归函数,用于打印最短路径上的节点。它依次回溯最短路径的前驱节点,直到到达起始节点。
6.在main函数中,首先读取输入数据。然后根据题目描述构建图的边,将起始节点和目标节点相连,以及节点i与节点i-b[i]相连。边的权重分别为1和0。
7.调用bfs函数计算最短路径。
8.最后,根据最短路径的结果进行输出。如果无法到达目标节点,则输出-1;否则输出最短路径长度和路径上的节点。

        总的来说,该代码解决了一个关于图的最短路径问题。它通过构建图和应用广度优先搜索算法来找到起始节点到目标节点的最短路径,并输出最短路径的长度和节点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向阳而生__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值