拼多多笔试 拼多多笔试题 20260315 春招实习笔试真题

笔试时间:2026年3月15日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题:直播排行榜

题目

多多负责多多直播的首页直播排行榜的巡检工作。今天平台一共收到 n 条候选直播内容,按输入顺序依次编号为 1 到 n。每条直播内容都属于某个主播。为了避免同一主播同时占据多个直播排行榜位置,正式生成榜单前,平台会先做一次主播去重:

  • 对于同一个主播,只保留该主播最优的一条直播内容进入候选榜单;
  • 同一主播的其他直播内容会在这一步直接被淘汰,不再参与后续排序。

因此,最终直播排行榜中每个主播至多出现一次,榜单条数恰好等于不同主播的个数。

一条直播内容是否更优,按以下顺序比较:

  1. 点赞数更多者更优;
  2. 如果点赞数相同,则评论数更多者更优;
  3. 如果点赞数和评论数都相同,则发布时间更早者更优(t_i 越小表示发布时间越早);
  4. 如果以上三项仍然完全相同,则原始编号更小者更优。

完成主播去重后,再对所有保留下来的直播内容按完全相同的规则排序,得到最终直播排行榜。

现在给出 q 个查询。每次查询一条直播内容的最终结果:

  • 如果这条直播条目最终出现在直播排行榜中,输出它的排名;
  • 如果它在主播去重阶段已经被淘汰,输出 0。

输入描述

第一行输入两个整数 n, q,分别表示候选直播内容数和查询条数。

接下来 n 行,第 i 行输入四个整数 u_i, a_i, b_i, t_i,表示第 i 条直播内容所属主播编号、点赞数、评论数和发布时间。其中,t_i 越小表示发布时间越早。

接下来 q 行,每行输入一个整数 id,表示询问编号为 id 的直播内容最终排名。

输出描述

输出 q 行,每行一个整数:若对应直播条目最终上榜,输出其排名,排名从 1 开始计数;否则输出 0。

补充说明

  • 1 ≤ n, q ≤ 2×10^5
  • 1 ≤ u_i ≤ 10^9
  • 0 ≤ a_i, b_i, t_i ≤ 10^9
  • 1 ≤ id ≤ n

样例输入

5 4
1 100 20 5
2 100 20 3
1 120 10 8
3 100 25 4
2 110 18 6
1
2
3
5

样例输出

0
0
1
2

样例说明

主播 1 有第 1、3 两条直播条目,其中第 3 条更优;主播 2 有第 2、5 两条直播条目,其中第 5 条更优;主播 3 只有第 4 条直播条目。因此候选榜单只剩第 3、4、5 条直播条目,再按规则排序后顺序为 3 > 5 > 4。

参考题解

解题思路:

这题分两步做。第一步先按主播去重:对于同一个主播,只保留最优的那条直播,比较规则就按题目给的四级优先级逐项比较。第二步把所有保留下来的直播再按同样规则整体排序,排完后记录每条保留直播的排名。这样查询时,如果某条直播没被保留,答案就是 0;如果被保留了,直接输出它的排名即可。整体就是一次哈希去重加一次排序。

C++

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

bool better_item(int i, int j, const vector<long long>& a, const vector<long long>& b, const vector<long long>& t) {
    if (a[i] != a[j]) return a[i] > a[j];
    if (b[i] != b[j]) return b[i] > b[j];
    if (t[i] != t[j]) return t[i] < t[j];
    return i < j;
}

void solve() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, q;
    cin >> n >> q;

    vector<long long> u(n + 1), a(n + 1), b(n + 1), t(n + 1);
    unordered_map<long long, int> mp;
    mp.reserve(n * 2 + 10);

    for (int i = 1; i <= n; i++) {
        cin >> u[i] >> a[i] >> b[i] >> t[i];
        long long x = u[i];
        if (!mp.count(x)) mp[x] = i;
        else {
            int j = mp[x];
            if (better_item(i, j, a, b, t)) mp[x] = i;
        }
    }

    vector<int> ids;
    ids.reserve(mp.size());
    for (auto &it : mp) ids.push_back(it.second);

    sort(ids.begin(), ids.end(), [&](int x, int y) {
        return better_item(x, y, a, b, t);
    });

    vector<int> ans(n + 1, 0);
    for (int i = 0; i < (int)ids.size(); i++) ans[ids[i]] = i + 1;

    while (q--) {
        int id;
        cin >> id;
        cout << ans[id] << '\n';
    }
}

int main() {
    solve();
    return 0;
}

Java

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

public class Main {
    static long[] a, b, t;

    static boolean betterItem(int i, int j) {
        if (a[i] != a[j]) return a[i] > a[j];
        if (b[i] != b[j]) return b[i] > b[j];
        if (t[i] != t[j]) return t[i] < t[j];
        return i < j;
    }

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

        int n = Integer.parseInt(st.nextToken());
        int q = Integer.parseInt(st.nextToken());

        long[] u = new long[n + 1];
        a = new long[n + 1];
        b = new long[n + 1];
        t = new long[n + 1];

        HashMap<Long, Integer> mp = new HashMap<>();

        for (int i = 1; i <= n; i++) {
            st = new StringTokenizer(br.readLine());
            u[i] = Long.parseLong(st.nextToken());
            a[i] = Long.parseLong(st.nextToken());
            b[i] = Long.parseLong(st.nextToken());
            t[i] = Long.parseLong(st.nextToken());
            long x = u[i];
            if (!mp.containsKey(x)) {
                mp.put(x, i);
            } else {
                int j = mp.get(x);
                if (betterItem(i, j)) mp.put(x, i);
            }
        }

        List<Integer> ids = new ArrayList<>(mp.values());
        ids.sort((x, y) -> betterItem(x, y) ? -1 : 1);

        int[] ans = new int[n + 1];
        for (int i = 0; i < ids.size(); i++) {
            ans[ids.get(i)] = i + 1;
        }

        for (int i = 0; i < q; i++) {
            int id = Integer.parseInt(br.readLine().trim());
            sb.append(ans[id]).append('\n');
        }
        System.out.print(sb);
    }
}

Python

import sys
from collections import defaultdict

input = sys.stdin.readline

def solve():
    n, q = map(int, input().split())

    u = [0] * (n + 1)
    a = [0] * (n + 1)
    b = [0] * (n + 1)
    t = [0] * (n + 1)

    mp = {}

    def better_item(i, j):
        if a[i] != a[j]: return a[i] > a[j]
        if b[i] != b[j]: return b[i] > b[j]
        if t[i] != t[j]: return t[i] < t[j]
        return i < j

    for i in range(1, n + 1):
        ui, ai, bi, ti = map(int, input().split())
        u[i], a[i], b[i], t[i] = ui, ai, bi, ti
        x = ui
        if x not in mp:
            mp[x] = i
        else:
            j = mp[x]
            if better_item(i, j):
                mp[x] = i

    from functools import cmp_to_key

    ids = list(mp.values())

    def cmp(x, y):
        if better_item(x, y):
            return -1
        return 1

    ids.sort(key=cmp_to_key(cmp))

    ans = [0] * (n + 1)
    for i, idx in enumerate(ids):
        ans[idx] = i + 1

    out = []
    for _ in range(q):
        id_ = int(input())
        out.append(str(ans[id_]))
    print('\n'.join(out))

solve()

第二题:电动车充电策略

题目

多多驾驶电动车从起点 0 出发,目的地距离为 L 公里。电动车满电时可行驶 C 公里,即电池容量为 C 公里续航。沿途有 n 个充电站,第 i 个充电站位于距离起点 dᵢ 公里处,充电价格为 pᵢ 每公里。

多多可以在任何充电站进行充电,充电量可以任意,但不能超过电池总容量。已知多多出发时电池处于满电状态。请你帮多多规划充电策略,求出到达目的地所需的最少充电费用。如果无论如何都无法到达目的地,请输出 -1。

输入描述

第一行包含三个整数 L, C, n,分别表示目的地距离、满电续航公里数、充电站的数量。

约束:1 ≤ L ≤ 10^9,1 ≤ C ≤ 10^9,1 ≤ n ≤ 5000

接下来 n 行,每行包含两个整数 dᵢ, pᵢ,分别表示第 i 个充电站距离起点的距离以及该站的充电单价。

约束:1 ≤ dᵢ < dᵢ₊₁ < L,1 ≤ pᵢ ≤ 10^9

输出描述

输出一行,一个整数,表示到达目的地的最少充电费用。若无法到达输出 -1。

样例输入1

20 10 3
4 5
9 2
15 6

样例输出1

24

样例说明1

起点满电(续航 10)。开至距离 9 的充电站,消耗 9 公里电量,剩余电量 1。在距离 9 的充电站充 9 公里电量达到满电,花费 9×2=18,此时电量 10。开至距离 15 的充电站,消耗 6 公里电量,剩余电量 4。在距离 15 的充电站充 1 公里电量,花费 1×6=6,此时电量 5。刚好开到终点 20(消耗 5),剩余电量 0。总费用:18+6=24。

样例输入2

20 5 1
10 5

样例输出2

-1

样例说明2

满电只能跑 5 公里,还没跑到第一个充电站就没电了,所以无法到达。

参考题解

解题思路:

经典贪心。站在当前充电站时,只看续航范围 C 内后面的站:如果能找到第一个价格比当前更便宜的站,那就只充到刚好能开到它;因为后面更便宜,没必要现在多买。否则说明在当前可达范围里没有更便宜的,那当前站就是这段范围里最划算的,就直接充满。一路这样贪心走下去即可。如果相邻两点之间距离超过 C,那根本到不了,直接输出 -1。由于 n ≤ 5000,直接枚举后面站点就能过。

C++

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

void solve() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    long long L, C;
    int n;
    cin >> L >> C >> n;

    vector<long long> d(n + 2), p(n + 2);
    d[0] = 0;
    p[0] = 0;
    for (int i = 1; i <= n; i++) cin >> d[i] >> p[i];
    d[n + 1] = L;
    p[n + 1] = 0;

    long long s = C;
    long long res = 0;
    for (int i = 0; i <= n; i++) {
        if (d[i + 1] - d[i] > C) {
            cout << -1 << '\n';
            return;
        }
        int to = -1;
        for (int j = i + 1; j <= n + 1 && d[j] - d[i] <= C; j++) {
            if (p[j] < p[i]) {
                to = j;
                break;
            }
        }
        long long need = C;
        if (to != -1) need = d[to] - d[i];
        if (s < need) {
            res += (need - s) * p[i];
            s = need;
        }
        s -= d[i + 1] - d[i];
    }
    cout << res << '\n';
}

int main() {
    solve();
    return 0;
}

Java

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

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

        long L = Long.parseLong(st.nextToken());
        long C = Long.parseLong(st.nextToken());
        int n = Integer.parseInt(st.nextToken());

        long[] d = new long[n + 2];
        long[] p = new long[n + 2];
        d[0] = 0;
        p[0] = 0;
        for (int i = 1; i <= n; i++) {
            st = new StringTokenizer(br.readLine());
            d[i] = Long.parseLong(st.nextToken());
            p[i] = Long.parseLong(st.nextToken());
        }
        d[n + 1] = L;
        p[n + 1] = 0;

        long s = C;
        long res = 0;
        boolean possible = true;

        for (int i = 0; i <= n; i++) {
            if (d[i + 1] - d[i] > C) {
                System.out.println(-1);
                return;
            }
            int to = -1;
            for (int j = i + 1; j <= n + 1 && d[j] - d[i] <= C; j++) {
                if (p[j] < p[i]) {
                    to = j;
                    break;
                }
            }
            long need = C;
            if (to != -1) need = d[to] - d[i];
            if (s < need) {
                res += (need - s) * p[i];
                s = need;
            }
            s -= d[i + 1] - d[i];
        }
        System.out.println(res);
    }
}

Python

import sys
input = sys.stdin.readline

def solve():
    L, C, n = map(int, input().split())

    d = [0] * (n + 2)
    p = [0] * (n + 2)
    for i in range(1, n + 1):
        d[i], p[i] = map(int, input().split())
    d[n + 1] = L
    p[n + 1] = 0

    s = C
    res = 0

    for i in

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

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

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

全部评论

相关推荐

评论
点赞
1
分享

创作者周榜

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