滴滴笔试 滴滴笔试题 20260308

笔试时间:2026年03月08日

往年笔试合集:

2023春招秋招笔试合集

2024春招秋招笔试合集

第一题:方格世界

难度:中等

涉及知识点: 差分数组与扫描线算法

题目描述

方格世界中所有方格的长宽高均为 1 米。方格世界中有 n 个方格堆,编号依次为 1~n。每个方格堆中的方格都是按照从下到上的方式堆成一列(假设有 k 个方格,则这 k 个方格堆成了一个长宽均为 1 米,高为 k 米的长方体)。初始时每个方格堆中的方格数量均为 0。方格世界会下 m 场"方格雨",第 i 场"方格雨"会使得编号在 l_i 到 r_i 之间的方格堆的方格数量增加 d_i。定义 f(h) 表示经过"方格雨"后方格世界中高度大于等于 h 米的方格堆个数。你需要计算 f(h) 中一共有多少不同的取值。

输入描述

输入第一行有两个整数 n(1 ≤ n ≤ 10^9)和 m(1 ≤ m ≤ 10^5),分别表示方格世界中方格堆的个数、"方格雨"的次数。接下来 m 行中,第 i 行有三个整数 l_i, r_i(1 ≤ l_i ≤ r_i ≤ n)和 d_i(1 ≤ d_i ≤ 10^4),分别表示"方格雨"作用的方格堆范围和增加的方格数量。

输出描述

输出一个整数,表示 f(h) 中一共有多少不同的取值。

样例

输入:

10 4
7 8 5
5 7 5
1 2 1
3 5 3

输出:

6 

说明:

第一场"方格雨"后各个方格堆中方格数量: [0 0 0 0 0 0 5 5 0 0];第二场"方格雨"后各个方格堆中方格数量: [0 0 0 0 5 5 10 5 0 0];第三场"方格雨"后各个方格堆中方格数量: [1 1 0 0 5 5 10 5 0 0];第四场"方格雨"后各个方格堆中方格数量: [1 1 3 3 8 5 10 5 0 0]。

依次计算 f(0)=10, f(1)=8, f(2)=6, f(3)=6, f(4)=4, f(5)=4, f(6)=3, f(7)=3, f(8)=3, f(9)=1, f(10)=1, f(11)=0。

f(h) 中一共有 6 个不同的取值。

参考题解

解题思路:

由于 f(h) 的值仅在 h 超过某个方格堆的高度时才发生变化,题目本质是求所有方格堆中出现了多少种不同的高度值。随着 h 变大,f(h) 会不断减小。只有当 h 恰好超过某一个方格堆的实际高度时,f(h) 的值才会发生变化。因此 f(h) 的不同取值个数 = 方格世界中出现的不同高度(大于0的高度)的种类数 + 1(高度为0的情况)。

我们利用差分思想将"方格雨"转化为坐标轴上的高度增减事件,按位置排序后通过扫描线累加得出各区间的高度,并用 Set 统计所有出现的不同正高度种类数,最后加 1(即高度为 0 的情况)即为答案。

Java:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        if (!scan.hasNextInt()) {
            return;
        }
        int limit = scan.nextInt();
        int opCount = scan.nextInt();

        Item[] items = new Item[opCount * 2];
        int index = 0;
        for (int j = 0; j < opCount; j++) {
            int start = scan.nextInt();
            int end = scan.nextInt();
            long diff = scan.nextLong();
            items[index++] = new Item(start, diff);
            items[index++] = new Item(end + 1, -diff);
        }

        Arrays.sort(items);

        long currentVal = 0;
        int lastPos = -1;
        Set<Long> resSet = new HashSet<>();
        for (int j = 0; j < items.length; j++) {
            Item it = items[j];
            if (lastPos != -1 && it.loc > lastPos) {
                if (currentVal > 0) {
                    resSet.add(currentVal);
                }
            }
            currentVal += it.delta;
            lastPos = it.loc;
        }
        System.out.println(resSet.size() + 1);
    }

    static class Item implements Comparable<Item> {
        int loc;
        long delta;

        public Item(int loc, long delta) {
            this.loc = loc;
            this.delta = delta;
        }

        @Override
        public int compareTo(Item target) {
            return Integer.compare(this.loc, target.loc);
        }
    }
}

C++:

#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;

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

    int n, m;
    if (!(cin >> n >> m)) return 0;

    vector<pair<int, long long>> events;
    events.reserve(m * 2);

    for (int j = 0; j < m; j++) {
        int start, end;
        long long diff;
        cin >> start >> end >> diff;
        events.push_back({start, diff});
        events.push_back({end + 1, -diff});
    }

    sort(events.begin(), events.end());

    long long currentVal = 0;
    int lastPos = -1;
    set<long long> resSet;

    for (auto& [loc, delta] : events) {
        if (lastPos != -1 && loc > lastPos) {
            if (currentVal > 0) {
                resSet.insert(currentVal);
            }
        }
        currentVal += delta;
        lastPos = loc;
    }

    cout << resSet.size() + 1 << endl;
    return 0;
}

Python:

import sys
from collections import defaultdict

def main():
    input_data = sys.stdin.read().split()
    idx = 0
    n = int(input_data[idx]); idx += 1
    m = int(input_data[idx]); idx += 1

    events = []
    for _ in range(m):
        start = int(input_data[idx]); idx += 1
        end = int(input_data[idx]); idx += 1
        diff = int(input_data[idx]); idx += 1
        events.append((start, diff))
        events.append((end + 1, -diff))

    events.sort()

    current_val = 0
    last_pos = -1
    res_set = set()

    for loc, delta in events:
        if last_pos != -1 and loc > last_pos:
            if current_val > 0:
                res_set.add(current_val)
        current_val += delta
        last_pos = loc

    print(len(res_set) + 1)

if __name__ == "__main_

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

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

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

全部评论

相关推荐

阿里云-基础设施事业部-云网络团队实习生招聘开始了团队介绍阿里云27届春季实习招聘已经启动!阿里云,阿里巴巴集团旗下云计算品牌,是全球前三、亚太第一的云计算、大数据和人工智能科技公司,致力于为政府、企业、研究机构和开发者,提供安全、可靠的计算和数据处理能力,让云计算和数据智能成为普惠技术。我们是洛神云网络团队,阿里云网络产品团队是阿里云飞天平台的核心,全球超过200个数据中心、19个地域及52个可用区、110个接入点,借助软件定义网络、高性能转发、云原生、分布式、硬件加速、AI调度等关键技术,构建云上云下全球互联的全链路高性能网络,洛神平台构建了超大规模、超高性能、极致弹性的云网络能力,目前支撑了VPC、ECS、SLB等关键产品,提供业内最丰富的网络资源及解决方案,服务阿里巴巴集团业务以及赋能全球数以百万企业客户进行数字化转型,承载了阿里集团云计算、电商、支付、物流等核心业务,也沉淀多篇SIGCOMM顶级会议论文和科技发明奖项。欢迎大家留言/邮件咨询,也可以投递简历到邮箱(见评论区),沟通校招岗位及面试流程(一对一沟通指导)。如果你想了解云计算如何解决企业级客户的痛点,如何降低客户成本,如何让客户更习惯在云上部署自己的服务,如何让客户的服务更加安全,通过技术的实现,让企业客户的在云上的更加灵活调度,满足日见增多的场景需求。你可以参与基础软件的设计、开发和维护,如分布式缓存系统、Linux操作系统等;如果你热衷于高性能分布式技术,你可以参与高性能分布式服务端程序的系统设计,为阿里云的网络产品提供强有力的后台支持,在海量的网络访问和数据处理中,设计强大的解决方案和&nbsp;高可扩展性的体系结构,满足日趋复杂的业务需求。为你准备:1、直接面向千万级应用场景,解决世界级技术难题,主管师兄一对一带你飞!2、各类培训实战交流,近距离接触阿里云底层核心技术多年实践和创新成果!3、不仅有最夯实的工程能力,也有最热门的前沿学术分享!4、最欢乐的团队氛围,最快乐的团建活动!招聘岗位AI&nbsp;Infra网络研发工程师工作地点:杭州、北京毕业时间:2026年11月-2027年10月岗位要求:1.计算机相关专业;2.良好的算法、数据结构基础,熟悉网络、数据库等技术;3.熟悉Java/C++/python任一门编程语言;4.对新技术保持热情,具备良好的分析、解决问题的能力;5.仅限27届毕业生,国内外院校皆可;6.具备系统思维与独立分析能力,良好的跨团队沟通协作能力,对网络系统和&nbsp;Al技术充满热情。
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

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