2024-01-06:用go语言,在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧 在桥上有一些石子,青蛙很讨厌踩在这些石子上 由于桥的长度和青蛙一次跳过的距离都是正整数 我们可以把独木桥
2024-01-06:用go語言,在河上有一座獨木橋,一只青蛙想沿著獨木橋從河的一側(cè)跳到另一側(cè)
在橋上有一些石子,青蛙很討厭踩在這些石子上
由于橋的長度和青蛙一次跳過的距離都是正整數(shù)
我們可以把獨木橋上青蛙可能到達的點看成數(shù)軸上的一串整點:0...L
其中L是橋的長度,坐標(biāo)為 0 的點表示橋的起點,坐標(biāo)為 L 的點表示橋的終點
青蛙從橋的起點開始,不停的向終點方向跳躍
一次跳躍的距離是 S 到 T 之間的任意正整數(shù)(包括S,T)
當(dāng)青蛙跳到或跳過坐標(biāo)為 L 的點時,就算青蛙已經(jīng)跳出了獨木橋。
題目給出獨木橋的長度 L,青蛙跳躍的距離范圍[S,T],
以及橋上石子的位置。
你的任務(wù)是確定青蛙要想過河,最少需要踩到的石子數(shù)。
來自華為社招筆試。
答案2024-01-06:
來自左程云。
靈捷3.5
大體步驟如下:
1.讀入橋的長度 L、跳躍的最小距離 S、最大距離 T 和石子的位置數(shù)組。
2.如果起點和終點相同,即 S 等于 T,則遍歷石子數(shù)組,計算能夠整除 S 的石子數(shù)量,并輸出結(jié)果。
3.否則,將石子位置數(shù)組排序,并計算可以減少的最小跳躍距離 cut,該值等于 S 和 T 之間的最小值。
4.初始化距離數(shù)組 distance,并將最小距離初始值設(shè)為 0。同時設(shè)置一個 stone 數(shù)組,記錄可能存在石子的位置。
5.遍歷石子位置數(shù)組,計算每個石子之間的距離,并將距離標(biāo)記在 distance 數(shù)組中,同時在 stone 數(shù)組中將對應(yīng)位置設(shè)為 true。
6.更新橋的長度為 distance 數(shù)組中的最后一個數(shù)和 cut 的較小值。
7.初始化 dp 數(shù)組,長度為橋的長度加一,并將每個位置的初始值設(shè)為 MAXN。
8.動態(tài)規(guī)劃求解 dp 數(shù)組,計算最少需要踩到的石子數(shù)。
- 對于每個位置 i,從 i-s 到 i-t 之間的位置 j,取 dp[j] 的最小值,再加上是否有石子的判斷 boolToInt(stone[i])。
9.遍歷 distance 數(shù)組的最后一個數(shù)加一到橋的長度 l,取 dp 數(shù)組中的最小值,即為最少需要踩到的石子數(shù)。
10.輸出結(jié)果。
總的時間復(fù)雜度是 O(m log m + l * t),其中 m 是石子數(shù)量,l 是橋的長度,t 是最大跳躍距離;
總的額外空間復(fù)雜度是 O(l + t)。
go完整代碼如下:
package main
import (
"fmt"
"sort"
)
const (
MAXN = 101
MAXL = 100001
MAXK = 201
)
var (
arr [MAXN]int
distance [MAXN]int
dp [MAXL]int
stone [MAXL]bool
reach [MAXK]bool
l, s, t, m, cut int
)
func main() {
inputs := []int{10,
2, 3, 5,
2, 3, 5, 6, 7}
ii := 0
l = inputs[ii]
ii++
s = inputs[ii]
ii++
t = inputs[ii]
ii++
m = inputs[ii]
ii++
for i := 1; i <= m; i++ {
arr[i] = inputs[ii]
ii++
}
if s == t {
ans := 0
for i := 1; i <= min(l, m); i++ {
if arr[i]%s == 0 {
ans++
}
}
fmt.Println(ans)
} else {
sort.Ints(arr[1 : m+1])
cut = reduce(s, t)
for i := 1; i <= m; i++ {
distance[i] = distance[i-1] + min(arr[i]-arr[i-1], cut)
stone[distance[i]] = true
}
l = min(l, distance[m]+cut)
for i := 1; i <= l; i++ {
dp[i] = MAXN
}
for i := 1; i <= l; i++ {
for j := max(i-t, 0); j <= i-s; j++ {
dp[i] = min(dp[i], dp[j]+boolToInt(stone[i]))
}
}
ans := MAXN
for i := distance[m] + 1; i <= l; i++ {
ans = min(ans, dp[i])
}
fmt.Println(ans)
}
}
func reduce(s int, t int) int {
for i := range reach {
reach[i] = false
}
cnt := 0
ans := 0
for i := 0; i < MAXK; i++ {
for j := i + s; j < min(i+t+1, MAXK); j++ {
reach[j] = true
}
if !reach[i] {
cnt = 0
} else {
cnt++
}
if cnt == t {
ans = i
break
}
}
return ans
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func boolToInt(b bool) int {
if b {
return 1
}
return 0
}
c++完整代碼如下:
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 101;
const int MAXL = 100001;
const int MAXK = 201;
int arr[MAXN];
int distance0[MAXN];
int dp[MAXL];
bool stone[MAXL];
bool reach[MAXK];
int l, s, t, m, cut;
int reduce(int s, int t) {
fill(reach, reach + MAXK, false);
int cnt = 0;
int ans = 0;
for (int i = 0; i < MAXK; i++) {
for (int j = i + s; j < min(i + t + 1, MAXK); j++) {
reach[j] = true;
}
if (!reach[i]) {
cnt = 0;
}
else {
cnt++;
}
if (cnt == t) {
ans = i;
break;
}
}
return ans;
}
int main() {
int inputs[] = { 10, 2, 3, 5, 2, 3, 5, 6, 7 };
int ii = 0;
l = inputs[ii++];
s = inputs[ii++];
t = inputs[ii++];
m = inputs[ii++];
for (int i = 1; i <= m; i++) {
arr[i] = inputs[ii++];
}
if (s == t) {
int ans = 0;
for (int i = 1; i <= min(l, m); i++) {
if (arr[i] % s == 0) {
ans++;
}
}
cout << ans << endl;
}
else {
sort(arr + 1, arr + m + 1);
cut = reduce(s, t);
for (int i = 1; i <= m; i++) {
distance0[i] = distance0[i - 1] + min(arr[i] - arr[i - 1], cut);
stone[distance0[i]] = true;
}
l = min(l, distance0[m] + cut);
for (int i = 1; i <= l; i++) {
dp[i] = MAXN;
}
for (int i = 1; i <= l; i++) {
for (int j = max(i - t, 0); j <= i - s; j++) {
dp[i] = min(dp[i], dp[j] + (stone[i] ? 1 : 0));
}
}
int ans = MAXN;
for (int i = distance0[m] + 1; i <= l; i++) {
ans = min(ans, dp[i]);
}
cout << ans << endl;
}
return 0;
}
c語言代碼如下:
#include <stdio.h>
#include <stdbool.h>
#define MAXN 101
#define MAXL 100001
#define MAXK 201
int arr[MAXN];
int distance[MAXN];
int dp[MAXL];
bool stone[MAXL];
bool reach[MAXK];
int l, s, t, m, cut;
int min(int a, int b) {
return a < b ? a : b;
}
int max(int a, int b) {
return a > b ? a : b;
}
int reduce(int s, int t) {
for (int i = 0; i < MAXK; i++) {
reach[i] = false;
}
int cnt = 0;
int ans = 0;
for (int i = 0; i < MAXK; i++) {
for (int j = i + s; j < (i + t + 1 < MAXK ? i + t + 1 : MAXK); j++) {
reach[j] = true;
}
if (!reach[i]) {
cnt = 0;
}
else {
cnt++;
}
if (cnt == t) {
ans = i;
break;
}
}
return ans;
}
void sortInts(int* arr, int size) {
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
void printAns(int ans) {
printf("%d\n", ans);
}
int main() {
int inputs[] = { 10, 2, 3, 5, 2, 3, 5, 6, 7 };
int ii = 0;
l = inputs[ii++];
s = inputs[ii++];
t = inputs[ii++];
m = inputs[ii++];
for (int i = 1; i <= m; i++) {
arr[i] = inputs[ii++];
}
if (s == t) {
int ans = 0;
for (int i = 1; i <= min(l, m); i++) {
if (arr[i] % s == 0) {
ans++;
}
}
printAns(ans);
}
else {
sortInts(arr + 1, m);
cut = reduce(s, t);
for (int i = 1; i <= m; i++) {
distance[i] = distance[i - 1] + min(arr[i] - arr[i - 1], cut);
stone[distance[i]] = true;
}
l = min(l, distance[m] + cut);
for (int i = 1; i <= l; i++) {
dp[i] = MAXN;
}
for (int i = 1; i <= l; i++) {
for (int j = max(i - t, 0); j <= i - s; j++) {
dp[i] = min(dp[i], dp[j] + (stone[i] ? 1 : 0));
}
}
int ans = MAXN;
for (int i = distance[m] + 1; i <= l; i++) {
ans = min(ans, dp[i]);
}
printAns(ans);
}
return 0;
}
總結(jié)
以上是生活随笔為你收集整理的2024-01-06:用go语言,在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧 在桥上有一些石子,青蛙很讨厌踩在这些石子上 由于桥的长度和青蛙一次跳过的距离都是正整数 我们可以把独木桥的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Supershell防溯源反制配置
- 下一篇: Havoc插件编写