当青训营遇上码上掘金
主题 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 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
以下为上图例子的解析:
输入: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)
}