拼多多校招笔试真题 10.18 - 叠放库位计数(C++/Py/Java /Js/Go)

叠放库位计数

拼多多 10月18号 笔试真题 第二题

拼多多真题目录点击查看: 拼多多笔试真题题库目录|笔试题库 + 算法考点详解

题目内容

仓储区的货架沿直线编号,每个编号对应一个库位,编号都是正整数。每张送货单会占住其中连续的一段,段的两头两个库位都要算进去。

给出一个门槛。请算出有多少个库位,被不少于这么多张送货单同时占住。

输入描述

第一行一个整数 t t t,表示门槛。

第二行一个整数 m m m,表示送货单张数。

后面再给出 m m m 行记录。每一行先写右端库位 b b b,再写左端库位 a a a。

1 ≤ m ≤ 10 5 1 \le m \le 10^5 1≤m≤105

1 ≤ t ≤ 10 9 1 \le t \le 10^9 1≤t≤109

1 ≤ a ≤ b ≤ 10 9 1 \le a \le b \le 10^9 1≤a≤b≤109

输出描述

输出一个整数,表示叠放次数达到门槛的库位个数。

样例1

输入

复制代码
2
3
6 2
8 4
9 5

输出

复制代码
5

说明

三张单分别占住 2 , 6 2,6 2,6、 4 , 8 4,8 4,8、 5 , 9 5,9 5,9。库位 4 4 4 到 8 8 8 的叠放次数都不低于 2 2 2,一共 5 5 5 个。库位 2 2 2、 3 3 3、 9 9 9 都只有一张单。

样例2

输入

复制代码
1
3
2 1
6 5
10 8

输出

复制代码
7

说明

三段分别是 1 , 2 1,2 1,2、 5 , 6 5,6 5,6、 8 , 10 8,10 8,10,彼此隔开。门槛为 1 1 1 时,这 2 + 2 + 3 = 7 2+2+3=7 2+2+3=7 个库位都要计入。

样例3

输入

复制代码
4
2
8 3
8 3

输出

复制代码
0

说明

两张单占的是同一段 3 , 8 3,8 3,8,任一库位最多被 2 2 2 张单占住,达不到门槛 4 4 4。

题解

思路

解题算法:差分 + 排序

  1. 因为每张送货单覆盖的是连续区间[a,b],由于题目给出的区间范围,不能直接开10^9的数组会爆内存,我们可以记录区间的变化位置,不需要逐个库位处理。
  2. 对于一个区间[a,b],在差分中记录:
    • 位置a,覆盖次数+1
    • 位置b+1,覆盖次数-1
  3. 然后对变化记录按照位置排序,然后从前往后进行扫描,统计相邻两个变化点之间有多少个库位满足覆盖次数不少于 t。
  4. 算法时间复杂度为O(mlogm)

C++

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

using ll = long long;

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

    ll t;
    int m;
    cin >> t >> m;

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

    for (int i = 0; i < m; i++) {
        ll b, a;
        cin >> b >> a;

        events.push_back({a, 1});
        events.push_back({b + 1, -1});
    }

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

    ll ans = 0;
    ll cover = 0;
    ll prev = events[0].first;

    int i = 0;
    while (i < (int)events.size()) {
        ll pos = events[i].first;

        // [prev, pos - 1] 这一段的覆盖次数为 cover
        if (cover >= t) {
            ans += pos - prev;
        }

        // 合并同一个位置的所有变化
        while (i < (int)events.size() && events[i].first == pos) {
            cover += events[i].second;
            i++;
        }

        prev = pos;
    }

    cout << ans << '\n';
    return 0;
}

java

java 复制代码
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        long t = sc.nextLong();
        int m = sc.nextInt();

        List<long[]> events = new ArrayList<>();

        for (int i = 0; i < m; i++) {
            long b = sc.nextLong();
            long a = sc.nextLong();

            events.add(new long[]{a, 1});
            events.add(new long[]{b + 1, -1});
        }

        events.sort((x, y) -> Long.compare(x[0], y[0]));

        long ans = 0;
        long cover = 0;
        long prev = events.get(0)[0];

        int i = 0;
        while (i < events.size()) {
            long pos = events.get(i)[0];

            // [prev, pos - 1] 这一段的覆盖次数为 cover
            if (cover >= t) {
                ans += pos - prev;
            }

            // 合并同一个位置的所有变化
            while (i < events.size() && events.get(i)[0] == pos) {
                cover += events.get(i)[1];
                i++;
            }

            prev = pos;
        }

        System.out.println(ans);
        sc.close();
    }
}

python

python 复制代码
import sys

input = sys.stdin.readline

t = int(input())
m = int(input())


events = []

for _ in range(m):
    b, a = map(int, input().split())

    events.append((a, 1))
    events.append((b + 1, -1))

events.sort()

ans = 0
cover = 0
prev = events[0][0]

i = 0
while i < len(events):
    pos = events[i][0]

    # [prev, pos - 1] 这一段的覆盖次数为 cover
    if cover >= t:
        ans += pos - prev

    # 合并同一个位置的所有变化
    while i < len(events) and events[i][0] == pos:
        cover += events[i][1]
        i += 1

    prev = pos

print(ans)

Go

go 复制代码
package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type Event struct {
	pos   int64
	delta int
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	var t int64
	var m int
	fmt.Fscan(reader, &t, &m)

	events := make([]Event, 0, 2*m)

	for i := 0; i < m; i++ {
		var b, a int64
		fmt.Fscan(reader, &b, &a)

		events = append(events, Event{a, 1})
		events = append(events, Event{b + 1, -1})
	}

	sort.Slice(events, func(i, j int) bool {
		return events[i].pos < events[j].pos
	})

	var ans int64 = 0
	var cover int64 = 0
	prev := events[0].pos

	i := 0
	for i < len(events) {
		pos := events[i].pos

		// [prev, pos - 1] 这一段的覆盖次数为 cover
		if cover >= t {
			ans += pos - prev
		}

		// 合并同一个位置的所有变化
		for i < len(events) && events[i].pos == pos {
			cover += int64(events[i].delta)
			i++
		}

		prev = pos
	}

	fmt.Fprintln(writer, ans)
}

javascript

js 复制代码
const readline = require('readline');

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

const input = [];

rl.on('line', line => {
    input.push(line.trim());
});

rl.on('close', () => {
    let idx = 0;
    const t = Number(input[idx++]);
    const m = Number(input[idx++]);
    const events = [];

    for (let i = 0; i < m; i++) {
        const [b, a] = input[idx++].split(' ').map(Number);

        events.push([a, 1]);
        events.push([b + 1, -1]);
    }

    events.sort((x, y) => x[0] - y[0]);

    let ans = 0;
    let cover = 0;
    let prev = events[0][0];

    let i = 0;
    while (i < events.length) {
        const pos = events[i][0];

        // [prev, pos - 1] 这一段的覆盖次数为 cover
        if (cover >= t) {
            ans += pos - prev;
        }

        // 合并同一个位置的所有变化
        while (i < events.length && events[i][0] === pos) {
            cover += events[i][1];
            i++;
        }

        prev = pos;
    }

    console.log(ans);
});
相关推荐
无限码力4 天前
拼多多笔试真题 10.11 - 测温共值最长段(C++/Py/Java /Js/Go)
pdd·拼多多笔试真题·拼多多技术岗笔试真题·拼多多秋招笔试真题·拼多多校招笔试真题
无限码力1 个月前
拼多多笔试真题 - 班次连窗日均(C++/Py/Java /Js/Go)
pdd·拼多多笔试真题·拼多多笔试题目题解·拼多多题库·拼多多机试真题
无限码力1 个月前
拼多多笔试真题题解 - 并箱放行(C++/Py/Java /Js/Go)
拼多多·拼多多笔试真题·拼多多笔试题解·拼多多9月6号笔试真题
无限码力1 个月前
拼多多笔试真题 9.6 - 看旗派舟(C++/Py/Java /Js/Go)
pdd·拼多多笔试真题·拼多多笔试·拼多多笔试真题题解·拼多多9月6号笔试真题
无限码力1 个月前
拼多多笔试真题 9.6 - 限次罐笼(C++/Py/Java /Js/Go)
pdd·拼多多笔试真题·拼多多笔试真题题解·拼多多笔试题解·拼多多9月6号笔试真题
无限码力2 个月前
拼多多笔试真题 2026-8-30【唯一入栈出库序列】
算法·pdd笔试真题·拼多多春招笔试真题·拼多多秋招笔试真题·拼多多笔试真题题解·拼多多最新笔试题库
无限码力2 个月前
2026-8-30拼多多笔试真题-哪个查阅窗能留空(C++/Py/Java /Js/Go)
算法·pdd·pdd笔试真题·拼多多春招笔试真题·拼多多秋招笔试真题·拼多多笔试真题题解·拼多多笔试题解
无限码力2 个月前
pdd笔试真题-和差方程最少标定(C++/Py/Java /Js/Go)
pdd·拼多多笔试真题·pdd笔试真题·拼多多技术岗笔试真题·拼多多秋招笔试·拼多多笔试题解
无限码力2 个月前
拼多多 春招&秋招 笔试真题题库目录|笔试题库 + 算法考点详解
算法·pdd笔试真题·pdd笔试真题题解·拼多多春招笔试真题·拼多多秋招笔试真题·拼多多笔试真题题解