【秋招笔试】2025.08.16淘天秋招研发岗机考改编题

✅ 秋招备战指南 ✅

💡 学习建议:

  • 先尝试独立解题
  • 对照解析查漏补缺

🧸 题面描述背景等均已深度改编,做法和题目本质基本保持一致。

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

🌸 目前本专栏已经上线100+套真题改编解析,后续会持续更新的

春秋招笔试机考招合集 -> 互联网必备刷题宝典🔗

题目一:小兰的图书整理方案

1️⃣:分离奇数和偶数序列,保持原始相对顺序

2️⃣:分别计算两个序列的最长严格递增子序列(LIS)长度

3️⃣:答案为两个LIS长度之和

难度:中等

这道题目的关键在于理解队列的FIFO特性和奇偶性限制,通过Dilworth定理将问题转化为求最长上升子序列。每个队列内必须严格递减才能保证最终输出的递减性,而最少的递减子序列数等于最长上升子序列的长度。

题目二:小毛的部门绩效优化

1️⃣:将权值公式拆解为行和与列和的线性组合

2️⃣:分别计算矩阵的行和与列和

3️⃣:使用贪心策略:大数配大数,分别排序后计算点积

难度:中等

这道题目的核心在于数学变形,将复杂的矩阵权值计算转化为两个独立的一维优化问题。通过排序后的贪心匹配,可以保证总权值最大化,体现了"同序配对使点积最大"的经典贪心思想。

题目三:小基的仓储选址优化

1️⃣:理解分段线性凸函数的性质

2️⃣:收集所有区间端点并排序

3️⃣:选择第n小的端点作为最优位置

难度:中等

这道题目是经典的几何中位数问题,关键在于理解每个区间对应的成本函数是分段线性的,总成本函数是凸函数。通过分析斜率变化,可以发现最优解就是所有端点的中位数,避免了复杂的数值优化。

01. 小兰的图书整理方案

问题描述

小兰是一名图书管理员,她负责整理图书馆的一批新书。这些新书有着不同的编号,需要按照编号从大到小的顺序重新排列上架。

小兰决定使用若干个临时书架来帮助整理这些图书。每个临时书架都按照先进先出的规则工作,即最先放入的书会最先被取出。整个整理过程分为两个阶段:

分配阶段:按照新书的原始顺序,小兰需要选择一个临时书架将每本书放入。但是有一个限制条件:如果临时书架中已经有书了,那么只能将编号奇偶性相同的书放入同一个书架。也就是说,奇数编号的书只能和奇数编号的书放在一起,偶数编号的书只能和偶数编号的书放在一起。

取出阶段:当所有书都分配完毕后,小兰开始从临时书架中取书上架。每一步,她可以选择任意一个临时书架,取出其顶部的书并放到最终的书架上。目标是让最终书架上的书按照编号严格从大到小的顺序排列。

显然,如果不限制临时书架的数量,这个任务很容易完成。所以你需要帮助小兰计算,至少需要多少个临时书架,才能完成上述整理流程并保证最终的书籍按编号严格递减排列。

输入格式

第一行包含一个正整数 ),表示图书的数量。

第二行包含 个整数 ),表示图书的编号序列。

输出格式

输出一个整数,表示至少需要多少个临时书架。

样例输入

9
8 4 2 5 3 7 1 6 0
4
1 2 3 4

样例输出

4
4
样例 解释说明
样例1 可以这样分配:第一个书架放入[8,4,2],第二个书架放入[5,3,1],第三个书架放入[7],第四个书架放入[6,0]。最终可以按8,7,6,5,4,3,2,1,0的顺序取出
样例2 由于每本书的编号都不同且需要严格递减输出,每本书都需要单独的书架

数据范围

题解

这道题本质上是一个贪心加动态规划的问题。关键在于理解题目的约束条件和最终目标。

首先分析问题的核心:我们需要将序列分成若干个子序列,每个子序列内的元素必须满足两个条件:

  1. 奇偶性相同
  2. 在原序列中的相对位置保持递减(这样才能保证最终输出时的递减性)

这样,问题就转化为:

  • 将所有奇数元素组成的子序列,分解为最少的严格递减子序列
  • 将所有偶数元素组成的子序列,分解为最少的严格递减子序列
  • 答案是两者之和

根据 Dilworth 定理,将序列分解为最少递减子序列的数量,等于该序列中最长严格递增子序列的长度。

具体算法步骤:

  1. 分别提取原序列中的奇数和偶数,保持相对顺序
  2. 对奇数序列求最长严格递增子序列(LIS)的长度
  3. 对偶数序列求最长严格递增子序列的长度
  4. 两个长度相加就是答案

时间复杂度为 ,使用经典的 LIS 算法即可处理 的数据范围。

参考代码

  • Python
import sys
input = lambda: sys.stdin.readline().strip()
from bisect import bisect_left

def calc_lis(arr):
    """计算严格递增LIS的长度"""
    if not arr:
        return 0
    
    tail = []  # tail[i] 表示长度为i+1的递增序列的最小结尾值
    for x in arr:
        pos = bisect_left(tail, x)
        if pos == len(tail):
            tail.append(x)
        else:
            tail[pos] = x
    return len(tail)

# 读取输入
n = int(input())
a = list(map(int, input().split()))

# 分离奇数和偶数序列
odd_seq = []
even_seq = []

for x in a:
    if x % 2 == 1:
        odd_seq.append(x)
    else:
        even_seq.append(x)

# 计算两个序列的LIS长度并相加
result = calc_lis(odd_seq) + calc_lis(even_seq)
print(result)
  • Cpp
#include <bits/stdc++.h>
using namespace std;

// 计算严格递增LIS的长度
int get_lis_len(const vector<int>& arr) {
    if (arr.empty()) return 0;
    
    vector<int> tail; // tail[i]表示长度为i+1的递增序列的最小结尾值
    for (int x : arr) {
        auto pos = lower_bound(tail.begin(), tail.end(), x);
        if (pos == tail.end()) {
            tail.push_back(x);
        } else {
            *pos = x;
        }
    }
    return tail.size();
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int n;
    cin >> n;
    
    vector<int> odd_nums, even_nums;
    
    // 读取数据并分离奇偶数
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        if (x & 1) {
            odd_nums.push_back(x);
        } else {
            even_nums.push_back(x);
        }
    }
    
    // 计算答案:两个LIS长度之和
    int ans = get_lis_len(odd_nums) + get_lis_len(even_nums);
    cout << ans << "\n";
    
    return 0;
}
  • Java
import java.util.*;

public class Main {
    // 计算严格递增LIS的长度
    public static int getLisLen(List<Integer> arr) {
        if (arr.isEmpty()) return 0;
        
        List<Integer> tail = new ArrayList<>();
        for (int x : arr) {
            int pos = Collections.binarySearch(tail, x);
            if (pos < 0) pos = -(pos + 1);
            
            if (pos == tail.size()) {
                tail.add(x);
            } else {
                tail.set(pos, x);
            }
        }
        return tail.size();
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        
        List<Integer> oddNums = new ArrayList<>();
        List<Integer> evenNums = new ArrayList<>();
        
        // 读取数据并分离奇偶数
        for (int i = 0; i < n; i++) {
            int x = sc.nextInt();
            if (x % 2 == 1) {
                oddNums.add(x);
            } else {
                evenNums.add(x);
            }
        }
        
        // 计算答案:两个LIS长度之和
        int result = getLisLen(oddNums) + getLisLen(evenNums);
        System.out.println(result);
    }
}

02. 小毛的部门绩效优化

问题描述

小毛是一家大型企业的人事总监,他负责管理公司的 个部门和 个项目。每个部门 都有一个基础权重 ,每个项目 都有一个难度系数

公司建立了一个 的绩效矩阵,其中第 个部门在第 个项目上的基础得分为

每个部门-项目组合的最终绩效评分计算公式为:

小毛可以对组织架构进行调整(但部门权重 和项目难度系数 保持不变):

  • 部门重组:交换任意两个部门的所有项目分配
  • 项目调整:交换任意两个项目在所有部门中的分配

小毛希望通过这些调整,使得公司的总绩效评分达到最大值。

输入格式

第一行包含两个正整数 ),分别表示部门数量和项目数量。

第二行包含 个正整数 ),表示各部门的基础权重。

第三行包含 个正整数 ),表示各项目的难度系数。

接下来 行,每行包含 个正整数 (),表示绩效矩

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

互联网刷题笔试宝典 文章被收录于专栏

互联网刷题笔试宝典,这里涵盖了市面上大部分的笔试题合集,希望助大家春秋招一臂之力

全部评论

相关推荐

------------------------------------题目一:题目大意:有&nbsp;n&nbsp;(1&nbsp;&lt;=&nbsp;n&nbsp;&lt;=&nbsp;2e5)&nbsp;本书,编号为&nbsp;ai&nbsp;(0&nbsp;&lt;=&nbsp;ai&nbsp;&lt;=&nbsp;1e9)。你需要将它们放入若干个临时书架(先进先出队列),要求奇数编号和偶数编号的书不能混放。最终,你需要从这些书架中按顺序取出书本,形成一个严格递减的序列。问最少需要多少个临时书架。解法思路:奇偶性限制使得奇数和偶数两组书的处理是完全独立的。对于每一组(例如奇数),为了能按顺序取出形成一个严格递减序列,放入同一个书架的书必须是原序列中的一个严格递减子序列。因此,问题转化为:将奇数子序列和偶数子序列分别拆分成最少数目的严格递减子序列。根据Dilworth定理,一个序列最少能被划分成的递减子序列的数量,等于其最长严格递增子序列(LIS)的长度。所以,分别求出奇数序列和偶数序列的LIS长度,两者相加即为答案。LIS可用经典的O(n&nbsp;log&nbsp;n)算法求解。------------------------------------题目二:题目大意:有&nbsp;n&nbsp;(1&nbsp;&lt;=&nbsp;n,&nbsp;m&nbsp;&lt;=&nbsp;1000)&nbsp;个部门和&nbsp;m&nbsp;个项目,部门权重为&nbsp;ai,项目难度为&nbsp;bj&nbsp;(1&nbsp;&lt;=&nbsp;a,&nbsp;b&nbsp;&lt;=&nbsp;1e4)。还有一个&nbsp;n&nbsp;x&nbsp;m&nbsp;的绩效矩阵&nbsp;vij&nbsp;(1&nbsp;&lt;=&nbsp;v&nbsp;&lt;=&nbsp;1e4)。总绩效为所有&nbsp;wij&nbsp;=&nbsp;vij&nbsp;*&nbsp;(ai&nbsp;+&nbsp;bj)&nbsp;的和。你可以任意交换部门的顺序(行和a的顺序),也可以任意交换项目的顺序(列和b的顺序),目标是最大化总绩效。解法思路:关键在于对总绩效公式进行数学变形。总绩效&nbsp;=&nbsp;Sum(vij&nbsp;*&nbsp;(ai&nbsp;+&nbsp;bj))&nbsp;=&nbsp;Sum(vij*ai)&nbsp;+&nbsp;Sum(vij*bj)。将求和顺序改变可得:Sum(ai&nbsp;*&nbsp;Sum_j(vij))&nbsp;+&nbsp;Sum(bj&nbsp;*&nbsp;Sum_i(vij))。这等价于&nbsp;`部门权重向量a`&nbsp;与&nbsp;`矩阵行和向量`&nbsp;的点积,加上&nbsp;`项目难度向量b`&nbsp;与&nbsp;`矩阵列和向量`&nbsp;的点积。根据排序不等式,两个向量的点积在它们同序排序时最大。因此,先计算出矩阵的所有行和与列和。然后,将部门权重a和行和向量都按降序排序后计算点积,再将项目难度b和列和向量都按降序排序后计算点积,两者相加即为最大总绩效。------------------------------------题目三:题目大意:有&nbsp;n&nbsp;(1&nbsp;&lt;=&nbsp;n&nbsp;&lt;=&nbsp;1e5)&nbsp;个服务区域,每个区域是数轴上的一个闭区间&nbsp;[li,&nbsp;ri]&nbsp;(|li|,|ri|&nbsp;&lt;=&nbsp;1e9)。你需要选择一个整数点&nbsp;x&nbsp;作为仓储中心,使得总运输成本最小。单个成本定义为:如果&nbsp;x&nbsp;在区间内,成本为0;否则成本是&nbsp;x&nbsp;到该区间最近端点的距离。解法思路:这是一个经典的几何中位数问题。总成本函数是所有单个成本函数的和,而每个单个成本函数&nbsp;`cost(x)`&nbsp;都是一个V形的凸函数。多个凸函数之和仍然是凸函数,其最小值点可以通过分析斜率变化找到。总成本函数的斜率在每个区间的端点&nbsp;`li`&nbsp;和&nbsp;`ri`&nbsp;处发生变化。当&nbsp;x&nbsp;从负无穷向正无穷移动时,初始总斜率为-n,每经过一个端点,斜率就加1。当斜率从负数变为非负数时,就到达了成本最小的位置。这个位置恰好是所有&nbsp;`2n`&nbsp;个端点(所有&nbsp;`li`&nbsp;和&nbsp;`ri`&nbsp;的集合)的中位数。因此,只需收集所有&nbsp;`2n`&nbsp;个端点,找到它们的中位数作为最优选址x,然后计算总成本即可。具体的详细代码和题解可以戳我主页的文章查看
投递阿里巴巴集团等公司10个岗位
点赞 评论 收藏
分享
SQL题写了几十行代码,艰难拿下
投递淘天集团等公司10个岗位
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务