【秋招笔试】0919携程秋招(已改编)-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试

💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历

✨ 本系列打算持续跟新 春秋招笔试题

👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸

✨ 笔试合集传送们 -> 🧷春秋招笔试合集

🍒 本专栏已收集 100+ 套笔试题,笔试真题 会在第一时间跟新

🍄 题面描述等均已改编,如果和你笔试题看到的题面描述不一样请理解,做法和题目本质基本不变。

🍹 感谢各位朋友们的订阅,你们的支持是我们创作的最大动力 💞

alt

🌈 携程秋招笔试,来啦!!!

🍥 这次笔试倒反天罡,粉丝反馈,感觉第一题倒是四题中最难调和写的,调了很久才过, 本次四题都包含了贪心的思路,名副其实的 贪心场!

1️⃣ 小学数学题,贪心+推公式

2️⃣ 排序+贪心,题目描述看起来很吓人,分析完之后不难

3️⃣ 二分答案的题目,需要分析出单调性质, check的时候可以贪心

4️⃣ 排序+贪心,需要分析出题目的性质,这点比较困难

🎁 01.LYA的宝藏探险 评测链接🔗

问题描述

LYA是一位热爱冒险的探险家。她最近发现了一个神秘的遗迹,这个遗迹是一个 的网格地图。地图的左上角坐标为 ,右下角坐标为 。每个格子 都藏有一件宝物,其价值为

LYA从左上角 开始她的探险。每一步,她可以选择向上、下、左、右四个方向中的一个移动到相邻的格子。每到达一个格子,LYA就能获得该格子中的宝物。

有趣的是,这个遗迹似乎有某种神奇的力量。当LYA离开一个格子后,该格子的宝物会立即重新出现,仿佛从未被取走过。

然而,LYA的探险时间有限。她最多只能移动 步。

现在,LYA想知道在有限的步数内,她最多能获得多少价值的宝物?

输入格式

第一行输入一个整数 ,表示询问的次数。

接下来 行,每行输入三个整数 ,分别表示地图的行数、列数和LYA最多可以移动的步数。

输出格式

输出 行,每行一个整数,表示对应询问中LYA能获得的最大宝物价值。

样例输入

1
2 2 5

样例输出

12

数据范围

题解

思维+推公式

来看看格子的价值分布。格子 的价值是 。这意味着随着 的增加,价值增加得更快(每次增加 ),而 的增加则相对缓慢(每次只增加 1)。

  1. 基于这个观察,可以得出一个重要结论:在大多数情况下,向下移动比向右移动更有价值。

  2. 那么,最优策略是什么呢?它分为几个阶段:

    • 首先,尽可能地向下移动,直到到达最后一行。
    • 然后,向右移动到最右边的列。
    • 如果还有剩余步数,就在最后一行来回移动(因为最后一行的价值最高)。
  3. 但是,如果 (即只有一列),那么在最后一列上下移动会比在最后一行左右移动更有价值。

参考代码

  • Cpp
#include <iostream>
using namespace std;
typedef long long LL;

void calculateMaxValue() {
    int n, m, k;
    cin >> n >> m >> k;
    LL ans = 0;

    // 处理垂直移动
    if (k >= n - 1) {
        k -= n - 1;
        ans += 1LL * (n - 1) * m * n / 2;
    } else {
        ans += 1LL * k * m * (k + 1) / 2;
        k = 0;
    }

    // 处理水平移动
    int lastRow = (n - 1) * m;
    if (k >= m - 1) {
        ans += 1LL * (lastRow + 1 + lastRow + m - 1) * (m - 1) / 2;
        k -= m - 1;
    } else {
        ans += 1LL * (lastRow + 1 + lastRow + k) * k / 2;
        k = 0;
    }

    // 处理剩余步数
    int maxVal = n * m - 1;
    int secondMax = maxVal - 1;
    if (k > 0) {
        ans += 1LL * (k + 1) / 2 * secondMax;
        ans += 1LL * k / 2 * maxVal;
    }

    cout << ans << "\n";
}

int main() {
    int t;
    cin >> t;
    while (t--) {
        calculateMaxValue();
    }
    return 0;
}
  • Java
import java.util.Scanner;

public class Main {
    public static void calculateMaxValue(Scanner scanner) {
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int k = scanner.nextInt();
        long ans = 0;

        // 处理垂直移动
        if (k >= n - 1) {
            k -= n - 1;
            ans += (long)(n - 1) * m * n / 2;
        } else {
            ans += (long)k * m * (k + 1) / 2;
            k = 0;
        }

        // 处理水平移动
        int lastRow = (n - 1) * m;
        if (k >= m - 1) {
            ans += (long)(lastRow + 1 + lastRow + m - 1) * (m - 1) / 2;
            k -= m - 1;
        } else {
            ans += (long)(lastRow + 1 + lastRow + k) * k / 2;
            k = 0;
        }

        // 处理剩余步数
        int maxVal = n * m - 1;
        int secondMax = maxVal - 1;
        if (k > 0) {
            ans += (long)(k + 1) / 2 * secondMax;
            ans += (long)k / 2 * maxVal;
        }

        System.out.println(ans);
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int t = scanner.nextInt();
        while (t-- > 0) {
            calculateMaxValue(scanner);
        }
        scanner.close();
    }
}
  • Python
def calculate_max_value():
    n, m, k = map(int, input().split())
    ans = 0

    # 处理垂直移动
    if k >= n - 1:
        k -= n - 1
        ans += (n - 1) * m * n // 2
    else:
        ans += k * m * (k + 1) // 2
        k = 0

    # 处理水平移动
    last_row = (n - 1) * m
    if k >= m - 1:
        ans += (last_row + 1 + last_row + m - 1) * (m - 1) // 2
        k -= m - 1
    else:
        ans += (last_row + 1 + last_row + k) * k // 2
        k = 0

    # 处理剩余步数
    max_val = n * m - 1
    second_max = max_val - 1
    if k > 0:
        ans += (k + 1) // 2 * second_max
        ans += k // 2 * max_val

    print(ans)

t = int(input())
for _ in range(t):
    calculate_max_value()

📚 02.图书馆整理员 评测链接🔗

问题描述

K小姐是一位图书馆整理员。她最近接到了一项特殊任务:整理一批新到的图书。这批图书共有 本,每本书都有一个独特的编号。

K小姐的任务是按照以下规则整理这些书:

  1. 每次她可以从书架上选择 本书。
  2. 本书中,编号最大和最小的差值不能超过
  3. 从这 本书中,她需要将编号最小的那本书永久移出书架。
  4. 其余的书则放回书架。

K小姐可以重复这个过程,直到无法找到符合条件的 本书为止。

现在,K小姐想知道经过这样的整理后,书架上最少会剩下多少本书。

输入格式

第一行包含三个整数 ,分别表示初始的书本数量、每次选择的书本数量和允许的最大编号差值。

第二行包含 个整数,表示每本书的编号。

输出格式

输出一个整数,表示经过整理后,书架上最少剩余的书本数量。

样例输入

4 3 3
1 2 3 6

样例输出

3

数据范围

  • 每本书的编号为不超过 的正整数

题解

滑动窗口+贪心

题目的核心要求:每次从 本书中移除编号最小的一本。这意味着我们应该尽可能多地执行这个操作,以最小化剩余的书本数量。

解题思路如下:

  1. 将所有书的编号排序。这样可以保证每次都能选到编号最小的书。
  2. 使用滑动窗口的方法,检查每个长度为 的连续子序列。
  3. 对于每个窗口,如果最大编号和最小编号的差值不超过 ,那么我们就可以执行一次操作,移除一本书。
  4. 统计可以执行操作的次数,最后剩余的书本数量就是初始数量减去操作次数。

间复杂度分析:

  • 排序的时间复杂度是
  • 滑动窗口的过程是线性的,时间复杂度为

因此,总的时间复杂度是 ,这对于给定的数据范围()是可以接受的。

参考代码

  • Python
# 读取输入
n, m, k = map(int, input().split())
books = list(map(int, input().split()))

# 对书本编号进行排序
books.sort()

# 初始化结果和滑动窗口的左右指针
result = n
left = 0

# 遍历所有可能的窗口
for right in range(n):
    # 当窗口大小达到 m 时
    if right - left + 1 == m:
        # 检查窗口内的最大和最小编号差是否不超过 k
        if books[right] - books[left] <= k:
            result -= 1  # 可以执行一次操作,减少一本书
        left += 1  # 移动左指针

# 输出结果
print(result)
  • Java
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 读取输入
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int k = scanner.nextInt();
        
        int[] books = new int[n];
        for (int i = 0; i < n; i++) {
            books[i] = scanner.nextInt();
        }
        
        // 对书本编号进行排序
        Arrays.sort(books);
        
        // 初始化结果和滑动窗口的左指针
        int result = n;
        int left = 0;
        
        // 遍历所有可能的窗口
        for (int right = 0; right < n; right++) {
            // 当窗口大小达到 m 时
            if (right - left + 1 == m) {
                

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

学长刷题笔记 文章被收录于专栏

这里收集了超全的刷题笔记,欢迎大家的订阅,会持续跟新的

全部评论

相关推荐

09-15 12:15
北京大学 Java
geiedaada:倒反天罡,北大爷团子都敢拒!
点赞 评论 收藏
分享
Yushuu:你的确很厉害,但是有一个小问题:谁问你了?我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了😆
点赞 评论 收藏
分享
1 1 评论
分享
牛客网
牛客企业服务