【得物笔试题汇总】2024-03-27-得物春招笔试题-三语言题解(CPP/Python/Java)

🍭 大家好这里是KK爱Coding ,一枚热爱算法的程序员

✨ 本系列打算持续跟新得物近期的春秋招笔试题汇总~

💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导

👏 感谢大家的订阅➕ 和 喜欢💗

01.假日作业计划

题目描述

K小姐即将进入假期,打算利用这段时间完成积压的作业。由于每天的精力状态不同,她每天能完成的作业数量也有所不同。为了在假期内高效完成作业,同时兼顾身体健康,K小姐制定了一份假日作业计划:每次完成一定量的作业后,都需要休息 1 1 1 天或 2 2 2 天(不能不休息,也不能连续休息超过 2 2 2 天),再继续投入学习。K小姐决定从假期的第 1 1 1 天或第 2 2 2 天开始学习。请问按照这样的计划,K小姐在假期内最多能完成多少作业呢?

输入格式

第一行包含一个正整数 n n n,表示假期的总天数。

第二行包含 n n n 个空格分开的非负整数 a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1,a2,,an,其中 a i a_i ai 表示K小姐在第 i i i 天能完成的作业数量。

输出格式

输出一个整数,表示K小姐在假期内最多能完成的作业总数。

样例输入

5
2 1 2 1 2

样例输出

6

数据范围

1 ≤ n ≤ 1 0 4 1 \leq n \leq 10^4 1n104
0 ≤ a i ≤ 1 0 4 0 \leq a_i \leq 10^4 0ai104

题解

本题可以使用动态规划解决。定义状态 f [ i ] [ 0 ] f[i][0] f[i][0] 表示在第 i i i 天学习时能完成的最大作业量, f [ i ] [ 1 ] f[i][1] f[i][1] 表示在第 i i i 天休息时能完成的最大作业量。

状态转移方程为:

f [ i ] [ 0 ] = max ⁡ ( f [ i − 1 ] [ 0 ] , f [ i − 1 ] [ 1 ] ) f[i][0] = \max(f[i-1][0], f[i-1][1]) f[i][0]=max(f[i1][0],f[i1][1])
f [ i ] [ 1 ] = f [ i − 1 ] [ 0 ] + a i f[i][1] = f[i-1][0] + a_i f[i][1]=f[i1][0]+ai

其中, a i a_i ai 表示第 i i i 天能完成的作业量。

最终答案为 max ⁡ ( f [ n ] [ 0 ] , f [ n ] [ 1 ] ) \max(f[n][0], f[n][1]) max(f[n][0],f[n][1]),即第 n n n 天学习或休息时能完成的最大作业总量。

时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( n ) O(n) O(n)

参考代码

  • Python
n = int(input())
a = list(map(int, input().split()))

f = [[0] * 2 for _ in range(n + 1)]
f[0][1] = float('-inf')

for i in range(1, n + 1):
    f[i][0] = max(f[i-1][0], f[i-1][1])
    f[i][1] = f[i-1][0] + a[i-1]

print(max(f[n][0], f[n][1]))
  • Java
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();
        }
        
        int[][] f = new int[n + 1][2];
        f[0][1] = Integer.MIN_VALUE;
        
        for (int i = 1; i <= n; i++) {
            f[i][0] = Math.max(f[i - 1][0], f[i - 1][1]);
            f[i][1] = f[i - 1][0] + a[i - 1];
        }
        
        System.out.println(Math.max(f[n][0], f[n][1]));
    }
}
  • Cpp
#include <iostream>
#include <algorithm>
using namespace std;

const int N = 1e4 + 5;
int n, a[N];
int f[N][2];

int main() {
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    
    f[0][1] = -2e9;
    
    for (int i = 1; i <= n; i++) {
        f[i][0] = max(f[i - 1][0], f[i - 1][1]);
        f[i][1] = f[i - 1][0] + a[i - 1];
    }
    
    cout << max(f[n][0], f[n][1]) << endl;
    
    return 0;
}

02.K小姐的项链

题目描述

K小姐收到了一条由 0 0 0 1 1 1 组成的项链作为生日礼物。由于项链的特殊设计,如果其中连续出现 110 110 110 这样的子串,项链就会自动断开。为了避免这种情况发生,K小姐想知道这条项链中最长的不包含 110 110 110 子串的连续部分的长度是多少。

输入格式

输入一行,包含一个只由 0 0 0 1 1 1 组成的字符串 S S S,表示项链的序列,其长度 1 ≤ ∣ S ∣ ≤ 1 0 6 1 \leq |S| \leq 10^6 1S106

输出格式

输出一个整数,表示最长的不包含 110 110 110 子串的连续部分的长度。

样例输入

01101001

样例输出

4

数据范围

  • 1 ≤ ∣ S ∣ ≤ 1 0 6 1 \leq |S| \leq 10^6 1S106

题解

这道题可以使用滑动窗口的思想来解决。我们维护一个滑动窗口,窗口内的子串就是当前不包含 110 110 110 的连续部分。遍历整个字符串,每次判断以当前位置结尾的最后三个字符是否为 110 110 110,如果不是,就将当前字符纳入窗口,并更新最长长度;如果是,就将窗口左端点移动到当前位置的前两个字符,重新开始统计。

时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( 1 ) O(1) O(1)

参考代码

  • Python
s = input()
n = len(s)
max_len = 0
cur_len = 0

for i in range(n):
    cur_len += 1
    if i >= 2 and s[i-2:i+1] == "110":
        cur_len = 2
    max_len = max(max_len, cur_len)

print(max_len)
  • Java
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.next();
        int n = s.length();
        int maxLen = 0;
        int curLen = 0;
        
        for (int i = 0; i < n; i++) {
            curLen++;
            if (i >= 2 && s.substring(i-2, i+1).equals("110")) {
                curLen = 2;
            }
            maxLen = Math.max(maxLen, curLen);
        }
        
        System.out.println(maxLen);
    }
}
  • Cpp
#include <iostream>
#include <string>
using namespace std;

int main() {
    string s;
    cin >> s;
    int n = s.size();
    int maxLen = 0;
    int curLen = 0;
    
    for (int i = 0; i < n; i++) {
        curLen++;
        if (i >= 2 && s.substr(i-2, 3) == "110") {
            curLen = 2;
        }
        maxLen = max(maxLen, curLen);
    }
    
    cout << maxLen << endl;
    return 0;
}

写在最后

📧 KK这边最近正在收集近一年互联网各厂的笔试题汇总,如果有需要的小伙伴可以关注后私信一下 KK领取~

在这里插入图片描述

  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值