【笔试刷题】滴滴-2026.03.22-第二套-改编真题

✅ 春招备战指南 ✅

💡 学习建议:

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

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

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

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

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

滴滴-2026.03.22-第二套

1. 小基 的前后仓差异匹配

问题描述

小基 在整理一条长度为 的货物记录数组

对于每个位置

  • 把区间 记作前缀
  • 把区间 记作后缀

她定义了两个量:

  • 前缀差异度
  • 后缀差异度

现在对每个前缀 ),都要在它右边找一个互不重叠的后缀 ,也就是要求 ,并让:

尽可能小。

请你计算下面这个总和:

输入格式

第一行输入一个整数 ,表示数组长度。

第二行输入 个整数 ,表示数组元素。

输出格式

输出一行一个整数,表示题目要求的总和。

样例输入

4
1 3 2 4

样例输出

3

数据范围

样例 解释说明
样例 1 前缀差异度依次是 ,后缀差异度依次是 。对前缀 分别取右侧最接近值后,贡献是 ,总和为

题解

先把两个量写开就会发现,这题其实分成了两步:

  1. 先快速求出所有
  2. 对每个 ,去右边的后缀差异度里找最接近的值。

一、怎么在线性时间求出

先看前缀。

设前缀 的最大值是 ,前缀和是 ,那么:

所以从左到右扫一遍,维护:

  • 当前前缀最大值;
  • 当前前缀元素和。

就能在 时间求出全部

后缀完全一样。设后缀 的最大值是 ,后缀和是 ,则:

从右到左扫一遍即可。

二、右边最接近的 怎么找

当我们枚举到某个前缀 时,只允许选择 ,也就是只能从集合:

里找最接近 的值。

这提示我们可以从右往左处理:

  • 枚举到 之前,先把 加进数据结构;
  • 这样数据结构里始终维护着所有合法的右侧后缀差异度。

接下来只要支持两件事:

  1. 插入一个值;
  2. 查询某个值的前驱和后继。

那么最优答案一定在这两个候选里产生。

三、为什么只看前驱和后继就够了

把当前要匹配的值记成

在一个有序集合里:

  • 所有小于等于 的值中,离它最近的一定是最大的那个,也就是前驱;
  • 所有大于等于 的值中,离它最近的一定是最小的那个,也就是后继。

所以只要比较这两个值与 的距离,较小者就是当前前缀的最优贡献。

四、Python 为什么用树状数组

C++ 可以直接用 multisetJava 可以用 TreeMap

Python 没有现成的平衡树,直接用列表插入会退化成 。这里更稳的做法是:

  1. 先把所有 离散化;
  2. 用树状数组维护每个值当前出现了几次;
  3. 通过前缀个数和第 小查询,找出前驱和后继对应的真实值。

这样每次插入和查询都是

五、复杂度分析

  • 计算所有
  • 从右到左做插入与查询:

总时间复杂度:

空间复杂度:

参考代码

  • Python
import sys
from bisect import bisect_left

input = lambda: sys.stdin.readline().strip()


class Fenwick:
    def __init__(self, n):
        self.n = n
        self.bit = [0] * (n + 1)

    def add(self, idx, val):
        while idx <= self.n:
            self.bit[idx] += val
            idx += idx & -idx

    def sum(self, idx):
        res = 0
        while idx > 0:
            res += self.bit[idx]
            idx -= idx & -idx
        return res

    def kth(self, k):
        idx = 0
        step = 1 << (self.n.bit_length() - 1)
        while step:
            nxt = idx + step
            if nxt <= self.n and self.bit[nxt] < k:
                idx = nxt
                k -= self.bit[nxt]
            step >>= 1
        return idx + 1


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

    f = [0] * (n + 1)
    g = [0] * (n + 2)

    pref_max = 0
    pref_sum = 0
    for i, x in enumerate(a, 1):
        pref_max = max(pref_max, x)
        pref_sum += x
        f[i] = pref_max * i - pref_sum

    suf_max = 0
    suf_sum = 0
    for i in range(n, 0, -1):
        x = a[i - 1]
        suf_max = max(suf_max, x)
        suf_sum += x
        g[i] = suf_max * (n - i + 1) - suf_sum

    vals = sorted(set(g[2 : n + 1]))
    fw = Fenwick(len(vals))

    ans = 0
    total = 0

    for i in range(n - 1, 0, -1):
        pos = bisect_left(vals, g[i + 1]) + 1
        fw.add(pos, 1)
        total += 1

        x = f[i]
        idx = bisect_left(vals, x)
        left_cnt = fw.sum(idx)

        best = 10**30

        if left_cnt > 0:
            pre = vals[fw.kth(left_cnt) - 1]
            best = min(best, abs(x - pre))

        if left_cnt < total:
            nxt = vals[fw.kth(left_cnt + 1) - 1]
            best = min(best, abs(x - nxt))

        ans += best

    print(ans)


if __name__ == "__main__":
    solve()
  • Cpp
#include <bits/stdc++.h>
using namespace std;

using int64 = long long;

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

    int n;
    cin >> n;

    vector<int64> a(n + 1), f(n + 1), g(n + 2);
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }

    int64 pref_max = 0, pref_sum = 0;
    for (int i = 1; i <= n; ++i) {
        pref_max = max(pref_max, a[i]);
        pref_sum += a[i];
        f[i] = pref_max * i - pref_sum;
    }

    int64 suf_max = 0, suf_sum = 0;
    for (int i = n; i >= 1; --i) {
        suf_max = max(suf_max, a[i]);
        suf_sum += a[i];
        g[i] = suf_max * (n - i + 1LL) - suf_sum;
    }

    multiset<int64> st;
    int64 ans = 0;

    for (int i = n - 1; i >= 1; --i) {
        st.insert(g[i + 1]);

        int64 x = f[i];
        auto it = st.lower_bound(x);
        int64 best = (1LL << 62);

        if (it != st.end()) {
            best = min(best, llabs(*it - x));
        }
        if (it != st.begin()) {
            --it;
            best = min(best, llabs(*it - x));
        }

        ans += best;
    }

    cout << ans << '\n';
    return 0;
}
  • Java
import java.io.*;
import java.util.*;

public class Main {
    static class FastScanner {
        private final InputStream in = System.in;
        private final byte[] buf = new byte[1 << 16];
        private int ptr = 0;
        private int len = 0;

        private int read() throws IOException {
            if (ptr >= len) {
                len = in.read(buf);
                ptr = 0;
                if (len <= 0) {
                    return -1;
                }
            }
            return buf[ptr++];
        }

    

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

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

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

全部评论

相关推荐

#&nbsp;wxg&nbsp;一面##&nbsp;1、linux是怎么实现并发的有了进程和线程就可以实现并发了吗##&nbsp;2、单核的CPU可以实现多线程嘛##&nbsp;3、虚拟地址是什么##&nbsp;4、程序的地址空间是什么样子的##&nbsp;5、虚拟内存解释一下##&nbsp;6、介绍一下TCP协议##&nbsp;7、这里TCP链接,所谓的链接,什么叫做链接呢##&nbsp;8、建立连接以后,客户端和服务端较建立之前,有什么差异呢(内核还有什么变化呢)##&nbsp;9、所以建立链接本质上是做了什么事情呢?##&nbsp;10、在网络世界中,什么叫做建立链接呢##&nbsp;11、TCP三次握手流程##&nbsp;12、ack的值是seq+1,那这里ack的值有什么作用呢?以及为什么要设定成+1呢?##&nbsp;13、那三次握手以后,这个ack的值还有用吗?(其他的值还有什么用)##&nbsp;14、TCP是保证有序的##&nbsp;15、TCP首次握手的话,会携带什么信息呢##&nbsp;16、那它是怎么做到可以寻址的呢?##&nbsp;17、如果两次握手会怎么样?##&nbsp;18、两次握手浪费的是哪里的资源呢?(服务端&nbsp;or&nbsp;客户端)##&nbsp;19、建立TCP以后,传送包的时候,需要得到确认,才会发送下一个包嘛##&nbsp;20、tcp建立连接的时候,是怎么确定滑动窗口大小的呢?##&nbsp;21、滑动窗口的调整会受哪些制衡##&nbsp;22、假如你信号变差了,滑动窗口会受到什么影响呢?##&nbsp;23、Linux系统提供了一些系统函数,去让我们做系统调用,你说说有什么?##&nbsp;24、send命令调用成功是怎么保证对端收到数据##&nbsp;算法:1、leecode&nbsp;105&nbsp;(改编:前中序,直接输出后序)2、leecode&nbsp;2393、leecode&nbsp;3294、leecode&nbsp;862(改编:换成小于,然后输出满足条件的数组)从正面来看吧,能面到这个部门属于是受宠若惊,也确实让我见识到了我还是太不行了,还得继续努力,尤其是计算机基础方面。面试官人很好,一直在教我,最后也告诉我要多学习基础方面,对职业生涯很有帮助。哪怕我面的很差,面试官依旧告诉我学习C++,他们部门是C++语言的(还是稍微给我一点希望的)从反面来看,我铁定是挂了,前面的计算机基础几乎炸了,后面还好,实习被说没有什么含金量,算法也没有都做出来。依旧没有打破一面挂的魔咒。我也不知道暑期其他大厂能不能再给机会了,腾讯是目前唯一收留我的,感觉前途真的有点渺茫。强中自有强中手,大抵是这个道理吧,哪怕我一直在坚持学习,也不知道未来究竟如何啊所以有没有大佬可以帮忙内推下呀,真的感谢了
27届求职交流
点赞 评论 收藏
分享
第三题我的解法:#include&lt;iostream&gt;#include&lt;cmath&gt;#include&lt;cstdio&gt;#include&lt;tuple&gt;#include&lt;string&gt;#include&lt;queue&gt;#include&lt;stack&gt;#include&lt;vector&gt;#include&lt;stdlib.h&gt;#include&lt;cstring&gt;#include&lt;algorithm&gt;#include&lt;map&gt;#include&lt;unordered_map&gt;using&nbsp;namespace&nbsp;std;vector&lt;int&gt;dfs(vector&lt;int&gt;a,vector&lt;vector&lt;int&gt;&gt;edge,&nbsp;int&nbsp;pre,&nbsp;int&nbsp;cur,&nbsp;int&nbsp;goal){if&nbsp;(cur&nbsp;==&nbsp;goal)&nbsp;return&nbsp;{&nbsp;cur&nbsp;};for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;edge[cur].size();&nbsp;i++){int&nbsp;p&nbsp;=&nbsp;edge[cur][i];if&nbsp;(p&nbsp;==&nbsp;pre)continue;vector&lt;int&gt;sub&nbsp;=&nbsp;dfs(a,&nbsp;edge,&nbsp;cur,&nbsp;p,&nbsp;goal);if&nbsp;(sub.size()&nbsp;!=&nbsp;0){sub.push_back(cur);return&nbsp;sub;}}return&nbsp;{};}int&nbsp;main(){int&nbsp;n,&nbsp;m;cin&nbsp;&gt;&gt;&nbsp;n&nbsp;&gt;&gt;&nbsp;m;vector&lt;int&gt;a(n&nbsp;+&nbsp;1);for&nbsp;(int&nbsp;i&nbsp;=&nbsp;1;&nbsp;i&nbsp;&lt;=&nbsp;n;&nbsp;i++)cin&nbsp;&gt;&gt;&nbsp;a[i];vector&lt;vector&lt;int&gt;&gt;edge(n&nbsp;+&nbsp;1);for&nbsp;(int&nbsp;i&nbsp;=&nbsp;1;&nbsp;i&nbsp;&lt;&nbsp;n;&nbsp;i++){int&nbsp;u,&nbsp;v;cin&nbsp;&gt;&gt;&nbsp;u&nbsp;&gt;&gt;&nbsp;v;edge[u].push_back(v);edge[v].push_back(u);}for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;m;&nbsp;i++){int&nbsp;x,&nbsp;u,&nbsp;v;cin&nbsp;&gt;&gt;&nbsp;x&nbsp;&gt;&gt;&nbsp;u&nbsp;&gt;&gt;&nbsp;v;if&nbsp;(x&nbsp;==&nbsp;1){vector&lt;int&gt;road&nbsp;=&nbsp;dfs(a,&nbsp;edge,&nbsp;0,&nbsp;u,&nbsp;v);for&nbsp;(int&nbsp;i=0;i&lt;road.size();i++){int&nbsp;num&nbsp;=&nbsp;road[i];a[num]&nbsp;=&nbsp;a[num]&nbsp;?&nbsp;0&nbsp;:&nbsp;1;}}if&nbsp;(x&nbsp;==&nbsp;2){vector&lt;int&gt;road&nbsp;=&nbsp;dfs(a,&nbsp;edge,&nbsp;0,&nbsp;u,&nbsp;v);int&nbsp;ans&nbsp;=&nbsp;0;int&nbsp;flag&nbsp;=&nbsp;1;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;road.size();&nbsp;i++){ans&nbsp;+=&nbsp;a[road[i]]&nbsp;*&nbsp;flag;flag&nbsp;*=&nbsp;2;}cout&nbsp;&lt;&lt;&nbsp;ans&nbsp;&lt;&lt;&nbsp;endl;}}return&nbsp;0;}
美团笔试
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

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