淘天笔试 淘天笔试题 2026春招实习笔试真题解析

笔试时间:2026年3月25日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题:糖果分配极值

题目

圣诞老人有 n 种糖果,第 i 种糖果有 cᵢ 个。他要把这些糖果分给 k 个小朋友。分配规则如下:

  • 每一种糖果必须全部分完;
  • 对于任意一种糖果,任意两个小朋友所分得的该种糖果的数量之差不超过 1。

在所有合法分配中,任选一个小朋友,统计其最终得到的糖果总数;求该数值在所有合法分配中可能达到的最小值与最大值。

换句话说,求在所有合法分配方案中,任意一个小朋友所能获得的糖果总数的最小值与最大值。

输入描述

每个测试文件均包含多组测试数据,第一行输入一个整数 T (1 ≤ T ≤ 2×10⁵) 代表数据组数,每组测试数据描述如下:

第一行输入两个整数 n, k (1 ≤ n ≤ 2×10⁵, 1 ≤ k ≤ 10⁹);

第二行输入 n 个整数 c₁, …, cₙ (0 ≤ cᵢ ≤ 10⁹)。

除此之外,保证单个测试文件的 n 之和不超过 5×10⁵。

输出描述

对于每组测试数据,输出两个整数:在所有合法分配中,单个小朋友可能得到的糖果总数的最小值与最大值。

样例输入

3
3 2
5 2 7
4 3
0 0 0 0
2 5
10 1

样例输出

6 8
0 0
2 3

参考题解

解题思路:

对某一种糖果,设数量为 cnt。因为要求任意两个小朋友分到的该种糖果数量差不超过 1,所以每个人拿到的数量只可能是 cnt / k 或 cnt / k + 1。因此,对某个固定小朋友来说,这一类糖果贡献的最小值是 cnt / k,最大值是 cnt / k + (cnt % k != 0 ? 1 : 0)。把所有种类逐个累加即可。

C++:

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;
    while (T--) {
        int n;
        long long k;
        cin >> n >> k;
        long long mn = 0, mx = 0;
        for (int i = 0; i < n; i++) {
            long long cnt;
            cin >> cnt;
            mn += cnt / k;
            mx += cnt / k;
            if (cnt % k) mx++;
        }
        cout << mn << ' ' << mx << '\n';
    }
    return 0;
}

Java:

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();

        int T = Integer.parseInt(br.readLine().trim());
        while (T-- > 0) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int n = Integer.parseInt(st.nextToken());
            long k = Long.parseLong(st.nextToken());

            st = new StringTokenizer(br.readLine());
            long mn = 0, mx = 0;
            for (int i = 0; i < n; i++) {
                long cnt = Long.parseLong(st.nextToken());
                mn += cnt / k;
                mx += cnt / k;
                if (cnt % k != 0) mx++;
            }
            sb.append(mn).append(' ').append(mx).append('\n');
        }
        System.out.print(sb);
    }
}

Python:

import sys
input = sys.stdin.readline

T = int(input())
for _ in range(T):
    n, k = map(int, input().split())
    c = list(map(int, input().split()))
    mn = 0
    mx = 0
    for cnt in c:
        mn += cnt // k
        mx += cnt // k
        if cnt % k != 0:
            mx += 1
    print(mn, mx)

第二题:最大字典序公共子序列

题目

给定两个长度为 n 的排列 p 和 q(均为 1∼n 的排列,元素两两不同),请在它们的公共子序列中,找到字典序最大的序列并输出。

输入描述

第一行输入一个整数 n (1 ≤ n ≤ 2×10⁵),表示排列的长度。

第二行输入 n 个整数 p₁, p₂, …, pₙ,表示排列 p。

第三行输入 n 个整数 q₁, q₂, …, qₙ,表示排列 q。

保证 p 与 q 都是 1∼n 的排列。

输出描述

第一行输出一个整数 k,表示答案序列的长度。

第二行输出 k 个整数,为这条字典序最大的公共子序列。

样例输入

5
2 5 3 1 4
5 2 4 3 1

样例输出

2
5 4

样例解释

两序列的公共子序列中,以 5 开头后,能够继续选择的最大元素为 4,得到 [5, 4]。与 [5, 1] 相比,第二个元素更大,因此 [5, 4] 字典序更大。

参考题解

解题思路:

因为 p 和 q 都是排列,每个数只出现一次,所以公共子序列本质上只和"相对顺序"有关。要让字典序最大,就要优先让前面的数尽量大,因此可以从大到小枚举数值 v。如果 v 在两个排列中的位置都还在当前答案末尾之后,就可以把它加入答案。这样贪心选出来的序列就是字典序最大的公共子序列。

C++:

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;

    vector<int> p(n), q(n);
    vector<int> pos_p(n + 1), pos_q(n + 1);

    for (int i = 0; i < n; i++) {
        cin >> p[i];
        pos_p[p[i]] = i;
    }
    for (int i = 0; i < n; i++) {
        cin >> q[i];
        pos_q[q[i]] = i;
    }

    int last_p = -1, last_q = -1;
    vector<int> ans;

    for (int val = n; val >= 1; val--) {
        if (pos_p[val] > last_p && pos_q[val] > last_q) {
            ans.push_back(val);
            last_p = pos_p[val];
            last_q = pos_q[val];
        }
    }

    cout << ans.size() << '\n';
    for (int i = 0; i < (int)ans.size(); i++) {
        if (i) cout << ' ';
        cout << ans[i];
    }
    cout << '\n';
    return 0;
}

Java:

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine().trim());

        int[] posP = new int[n + 1];
        int[] posQ = new int[n + 1];

        StringTokenizer st = new StringTokenizer(br.readLine());
        for (int i = 0; i < n; i++) {
            int val = Integer.parseInt(st.nextToken());
            posP[val] = i;
        }
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < n; i++) {
            int val = Integer.parseInt(st.nextToken());
            posQ[val] = i;
        }

        int lastP = -1, lastQ = -1;
        List<Integer> ans = new ArrayList<>();

        for (int val = n; val >= 1; val--) {
            if (posP[val] > lastP && posQ[val] > lastQ) {
                ans.add(val);
                lastP = posP[val];
                lastQ = posQ[val];
            }
        }

        StringBuilder sb = new StringBuilder();
        sb.append(ans.size()).append('\n');
        for (int i = 0; i < ans.size(); i++) {
            if (i > 0) sb.append(' ');
            sb.append(ans.get(i));
        }
        sb.append('\n');
        System.out.print(sb);
    }
}

Python:

import sys
input = sys.stdin.readline

def main():
    n = int(input())
    p = list(map(int, input().split()))
    q = list(map(int, input().split()))

    pos_p = [0] * (n + 1)
    pos_q = [0] * (n + 1)

    for i in range(n):
        pos_p[p[i]] = i
    for i in range(n):
        pos_q[q[i]] = i

    last_p = -1
    last_q = -1
    ans = []

    for val in range(n, 0, -1):
        if pos_p[val] > last_p and pos_q[val] > last_q:
            ans.append(val)
            last_p = pos_p[val]
            last_q = pos_q[val]

    print(len(ans))
    print(' '.join(map(str, ans)))

main()

第三题:第k个喜欢数

题目

Tk 不喜欢能被 3 整除的正整数,也不喜欢十进制表示中包含数字 '3' 的正整数。现在他要将所有他喜欢的正整数按升序排成一个序列。给定正整数 k,请你找出这个序列的第 k 个数。

友情提醒:第 10¹⁸ + 1 项为 10 995 467 216 611 448 857。

输入描述

第一行输入一个整数 t (1 ≤ t ≤ 10⁴),表示测试用例的数量;

接下来

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

2025 春招笔试合集 文章被收录于专栏

2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南

全部评论

相关推荐

评论
点赞
3
分享

创作者周榜

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