当青训营遇上码上掘金

82 阅读2分钟

当青训营遇上码上掘金

主题 3:寻友之旅

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

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

分析题易知,涉及的位置在0-2k,所以直接从n开始bfs复杂度为o(2*k),找最短路

具体就是bfs,每次从队列中取一个pos,按三种情况走,如果要走的位置被访问过了就不入队列,否则入队列,直到遇到终点k,中途记录下走的距离,当遇到终点n时就输出答案

c++代码

#include<bits/stdc++.h>
using namespace std;
int vis[200005];
int main(){
    int n, k;
    cin >> n >> k;
    queue<int>q;
    q.push(n);
    vis[n] = 1;
    int ans = 0;
    while(!q.empty()){
        queue<int>p;
        while(!q.empty()){
            int now = q.front();
            q.pop();
            if(now == k){
                cout << ans; return 0;
            }
            if(now < k && !vis[now + 1]){
                p.push(now + 1);
                vis[now + 1] = 1;
            }
            if(now - 1 >= 0 && !vis[now - 1]){
                p.push(now - 1);
                vis[now - 1] = 1;
            }
            if(now < k && !vis[now * 2]){
                p.push(now * 2);
                vis[now * 2] = 1;
            }
        }
        q = p;
        ans ++;
    }
}
  • 主题 4:攒青豆

现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)

image.png

以下为上图例子的解析:

输入:height = [5,0,2,1,4,0,1,0,3]
输出:17
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。

标准接雨水,从两边向中间遍历,并记录水位高度,每次更新水位高度,并统计答案

具体,用l,r代表两边位置,high为当前水位高度,则每次有:

high=max(high, min(arr[l], arr[r]))

ans += high - min(arr[l], arr[r]))

if arr[l] > arr[r], r--

else l++;

直到r==l时输出答案ans

c++代码

#include<bits/stdc++.h>
using namespace std;
int arr[1000000];
int main(){
    int n = 0, x;
    while(cin >> x)arr[n++] = x;
    int l = 0, r = n - 1, high = 0;
    long long ans = 0;
    while(l < r){
        high = max(high, min(arr[l], arr[r]));
        ans += high - min(arr[l], arr[r]);
        if(arr[l] > arr[r])r--;
        else ans += high - arr[l], l++;
    }
    cout << ans;
}

提交的go代码

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"math"
	"os"
	"strconv"
	"strings"
)

func main() {
	input := bufio.NewReader(os.Stdin)
	s, ok := input.ReadBytes('\n')
	if ok != nil {
		fmt.Println(ok)
	}
	s = bytes.TrimSuffix(s, []byte("\n"))
	var arr []int
	for _, val := range strings.Split(string(s), " ") {
		num, _ := strconv.Atoi(val)
		arr = append(arr, num)
	}
	l, r := 0, len(arr)-1
	high, ans := 0, 0
	for l < r {
		high = int(math.Max(float64(high), math.Min(float64(arr[l]), float64(arr[r]))))
		if arr[l] > arr[r] {
			ans += high - arr[r]
			r--
		} else {
			ans += high - arr[l]
			l++
		}
	}
	fmt.Println(ans)
}