拼多多笔试 拼多多笔试题 0409

笔试时间:2025年04月09日

历史笔试传送门:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题

题目:披萨餐厅

Gerry的店里有n个顾客使用兑换券兑换m个糖果。单张兑换券可以兑换k个糖果。 单次兑换所需的兑换券数y与糖果数x有如下关系,类似四舍五入:y=⌈x/k⌉,(if x mod k >= ⌈k/2⌉)y=⌊x/k⌋,(if x mod k < ⌈k/2⌉)*注:⌈⌉代表向上取整,⌊⌋代表向下取整,mod代表取模。 Gerry有如下要求:每个顾客最多交易1次m个糖果需要全部兑换完Gerry想知道要兑换完所有的糖果,至少需要多少张兑换券,请帮忙计算一下。

输入描述

第一行个数字T(1≤T≤1000)

接下来T行,每行三个数字:

n,m,k;(1 ≤n≤10^9,1 ≤m ≤10^18,2≤k≤10^9)

输出描述

输出T行,每行一个数字,代表最少需要用的兑换券个数

样例输入

3

3 300 100

36 96 6

73 176 22

样例输出

2

4

0

参考题解

贪心,为了不让优惠券亏掉,先让n-1个人都用一张券换最多的糖果,剩下的糖果都让最后一个人来换,这样消耗的优惠券数量最少。

C++:[此代码未进行大量数据的测试,仅供参考]

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

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

    int T;
    cin >> T;
    while (T--) {
        long long n, m, k;
        cin >> n >> m >> k;

        long long res = 0;
        long long t = (k + 1) / 2 - 1;
        m -= t * (n - 1);
        if (m <= 0) {
            cout << 0 << "\n";
            continue;
        }
        long long yu = m % k;
        res += m / k;
        if (yu > t) {
            res++;
        }
        cout << res << "\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 T = Integer.parseInt(br.readLine());
        while (T-- > 0) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            long n = Long.parseLong(st.nextToken());
            long m = Long.parseLong(st.nextToken());
            long k = Long.parseLong(st.nextToken());

            long res = 0;
            long t = (k + 1) / 2 - 1;
            m -= t * (n - 1);
            if (m <= 0) {
                System.out.println(0);
                continue;
            }
            long yu = m % k;
            res += m / k;
            if (yu > t) {
                res++;
            }
            System.out.println(res);
        }
    }
}

Python:[此代码未进行大量数据的测试,仅供参考]

def solve():
    n, m, k = map(int, input().split())
    res = 0
    t = (k + 1) // 2 - 1
    m -= t * (n - 1)
    if m <= 0:
        print(0)
        return
    yu = m % k
    res += m // k
    if yu > t:
        res += 1
    print(res)


T = int(input())
for _ in range(T):
    solve()

第二题

题目:操作数列

多多有两个仅由正整数构成的数列 s1 和 s2,多多可以对 s1进行任意次操作,每次操作可以置换 s1中任意两个数字的位置.多多想让数列 s1 构成的数字尽可能大,但是不能比数列 s2构成的数字大.请问再经过任意次操作后,满足上述条件的数列 s1构成的数字是多少?

输入描述

第一行,包含一个正整数T(1 ≤T≤10)代表测试数据的组数

对于每组测试数据,分别有三行:第一行,有两个正整数 n(1 <n<10^5),m(1 ≤m ≤ 10^5),分别表示数列 s1 和 s2 的长度

第二行,有一行仅由正整数组成的的长度为 n 数列 s1.

第三行,有一行仅由正整数组成的的长度为 m 数列 s2

输出描述

对于每组数据,输出数列 s1在经过任意次置换操作后,得到的满足条件的最大值数字.如果不存在这样的数字,则输出 -1.

样例输入

3

5 5

12748

34514

5 5

18715

51721

5 5

69568

52137

样例输出

28741

51718

-1

参考题解

位数差异判断当s1位数 < s2位数:直接降序排列s1即可(位数少必然更小)当s1位数 > s2位数:必然无法满足条件,直接返回-1等长时的构造策略从高位到低位遍历,每个位置尽可能选最大的可用数字需满足两种情况之一: a. 当前位数字严格小于s2对应位,后续位可以填最大可用数 b. 当前位数字等于s2对应位,继续按相同规则处理下一位若无法满足上述条件则需要回溯关键难点需要处理数字重复使用的情况(用计数器统计剩余可用数字)通过栈模拟回溯过程,当然递归应该也可以,python选手注意栈空间。维护"是否已存在某位比s2小"的状态,决定后续位的自由度。

C++:[此代码未进行大量数据的测试,仅供参考]

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

struct State {
    int index;
    bool iless;
    State(int i, bool l) : index(i), iless(l) {}
};

void solve() {
    int N, M;
    cin >> N >> M;
    string s1, s2;
    cin >> s1 >> s2;

    // 情况1:s1 位数 < s2 位数,直接输出 s1 的最大排列
    if (N < M) {
        vector<int> cnt(10, 0);
        for (char c : s1) {
            cnt[c - '0']++;
        }
        // 从 9 到 0 降序拼接
        for (int d = 9; d >= 0; d--) {
            for (int k = 0; k < cnt[d]; k++) {
                cout << char('0' + d);
            }
        }
        cout << "\n";
        return;
    }

    // 情况2:s1 位数 > s2 位数,直接返回 -1
    if (N > M) {
        cout << "-1\n";
        return;
    }

    // 情况3:等长时,需要在不超过 s2 的前提下,用 s1 的数字拼最大数
    vector<int> cnt(10, 0);
    for (char c : s1) {
        cnt[c - '0']++;
    }
    vector<char> ans(N, '\0');  // 最终答案字符数组,初始都为 '\0'

    // 栈模拟回溯:存放 (当前处理位 index, 是否已小于 s2 的标志 iless)
    vector<State> stk;
    stk.reserve(N + 5);
    stk.emplace_back(0, false);

    while (!stk.empty()) {
        State &top = stk.back();
        int index = top.index;
        bool iless = top.iless;

        // 如果 index == N,已经构造出一个合法解
        if (index == N) {
            for (char c : ans) {
                cout << c;
            }
            cout << "\n";
            return;
        }

        // 计算当前位可尝试的最大数字 sdval
        int sdval;
        if (ans[index] == '\0') {
            // 首次处理该位
            int limit = iless ? 9 : (s2[index] - '0');
            sdval = limit;
        } else {
            // 回溯时:先把之前使用的数字归还,再尝试更小的
            int prevDigit = ans[index] - '0';
            cnt[prevDigit]++;
            ans[index] = '\0';
            sdval = prevDigit - 1;
        }

        bool foundNext = false;
        // 从 sdval 向下尝试可用数字
        for (int d = sdval; d >= 0; d--) {
            if (cnt[d] > 0) {
                ans[index] = char('0' + d);
                cnt[d]--;
                bool nextIless = iless || (d < (s2[index] - '0'));
                stk.emplace_back(index + 1, nextIless);
                foundNext = true;
                break;
            }
        }

        if (!foundNext) {
            // 本位所有数字都不行,回溯
            stk.pop_back();
        }
    }

    // 尝试完所有可能性,仍未构造出解
    cout << "-1\n";
}

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

    int T;
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}

Java:[此代码未进行大量数据的测试,仅供参考]

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

public class Main {
    static void solve(BufferedReader br, StringBuilder sb) throws IOException {
        StringTokenizer st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());
        String s1 = br.readLine().trim();
        String s2 = br.readLine().trim();

        // 情况1:s1 位数 < s2 位数,直接输出 s1 的最大排列
        if (N < M) {
            int[] cnt

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

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

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

全部评论

相关推荐

昨天 10:03
前端工程师
点赞 评论 收藏
分享
一面(42min)5.23迟到了五分钟,面试官脾气真好居然没骂我先自我介绍项目拷打:问了强化学习的项目,具体的建模方式,奖励函数是怎么设计的,输入特征有多少?为什么用value&nbsp;based模型不用policy&nbsp;based模型?dqn结构怎么设计?训练了多久?挖掘了很多建模和求解细节。然后问了在滴滴做的预测项目,这个问的比较少,主要是深度学习的一些八股,比如FM的原理和优点。手撕:最大重复订单数反问:问了下对方是什么业务,因为饿了么面试只显示岗位是机器学习,不知道具体是哪个部门;然后问了对方强化学习在业务里的集体应用。周五面的,下一周的周一通过,约了二面二面(50min)5.27面试官上来先聊了下他们做的一些业务方向,是饿了么订单分配相关的,然后问我对业务有什么问题,可以先讨论下,如果我想先面试的话也可以。我说那先面试吧,业务问题等面完再交流。先是自我介绍,基本和一面一样。面试官听完后,说我的科研项目和实习项目都和他们实际业务比较相关,然后逐一拷打了我的论文项目和实习项目,有些问题和一面差不多,这里挑一些新的问题介绍一下:为什么在论文中选用了dqn?是基于什么考虑?创新点在哪里?论文里有涉及区域聚类,是基于城市土地信息来划定类别还是基于订单分布?baseline是什么?比较的效果怎么样?预测项目拷打的比一面更细,仔细了解了每个头输出的label,以及其中具体某个label在预测中的准确度问题和解决方案;还讨论了分场景下的预测是怎么做的。手撕:一个数组&nbsp;每个数可以减去在自己右边的数&nbsp;求差的最大值场景建模题:三个订单,分别有商家位置和用户位置,要规划一条路径去送餐,其中每个订单有时间窗限制,问应该如何建模?最后讨论了论文的场景复用到外卖供需调度场景的可能性和挑战。反问:也是问了强化学习在分单中的应用;还有岗位是否要求立即到岗。面试官非常有礼貌,基本都是先把自己的问题罗列一遍,然后让我逐一去回答,过程中也不会突然打断,面试体验非常棒。第二天通过,约了hr面hr面(65min)5.30一开始说大概面30-40分钟,后来逐渐失控...省去了自我介绍的环节,主要从以下几个维度来提问:实习经历:看到我这边有两段实习,主要问了在滴滴的实习经历,大致描述下整个实习过程做了什么,整个链路是怎么样的?最大的挑战是什么?最亮眼的产出是什么?上一顿实习有什么遗憾?项目是独立做的还是团队合作?学习一个新模型的思路是什么?通过哪些途径?在大公司实习和小公司有什么区别?哪个带来的成长更多?过往的学习经历:为什么本科选了这个专业?是因为高中就有相应规划还是依据高考分数选的?为什么考研现在这个专业?为什么来找算法岗的工作?觉得过往经历中对自己帮助最大的两件事是什么?未来规划:从现在开始到未来的某个时间节点,最想做好的三件事是什么?入职三年的职业规划是什么样的?对饿了么的看法:对饿了么有什么认识?评价怎么样?平时用的过程中有哪些问题?和其他offer相比,它的优势和劣势分别是什么?整体还聊了很多,有些记不起来了,反正都是些开放类的问题,侃侃而谈即可。6.5号意向&nbsp;&nbsp;&nbsp;&nbsp;
投递饿了么等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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