C++ 算法竞赛 题目解析:Intersection 交集(区间重叠长度)

0 阅读3分钟

1. 题目

Intersection 交集(区间重叠长度)

性能限制

内存: 128 MB,时间: 1 S

题目信息

在这里插入图片描述 在这里插入图片描述

输入输出样例

输入样例1
0 3 1 5
输出样例1
2

(区间 [0,3] 与 [1,5] 重叠部分为 [1,3],长度 2)

输入样例2
0 1 4 5
输出样例2
0

(区间 [0,1] 与 [4,5] 无重叠)

输入样例3
0 3 3 7
输出样例3
0

( [0,3] 与 [3,7] 仅在点 3 相交,长度为 0。)

数据范围与提示

在这里插入图片描述


2. 代码

标准版本(可读性好)

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

int main() {
    int L1, R1, L2, R2;
    cin >> L1 >> R1 >> L2 >> R2;

    int overlap_left = max(L1, L2);
    int overlap_right = min(R1, R2);
    int length = max(0, overlap_right - overlap_left);

    cout << length << endl;
}

极简版本(一行输出)

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

int main() {
    int L1, R1, L2, R2;
    cin >> L1 >> R1 >> L2 >> R2;
    cout << max(0, min(R1, R2) - max(L1, L2));
}

3. 解析

3.1 问题本质

给定两个闭区间 [L1, R1][L2, R2],求它们重叠部分的整数长度(或连续长度)。
通常定义长度为 右端点 - 左端点(若重叠部分退化为一个点,长度为 0)。

3.2 核心思路

两个区间的交集仍然是一个区间(可能为空),其左右端点由下式确定:

  • 交集左端点 = max(L1, L2)
  • 交集右端点 = min(R1, R2)

原因
要同时属于两个区间,
左端点必须 >= 两个左端点中的较大者;
右端点必须 <= 两个右端点中的较小者。

max(L1, L2) >= min(R1, R2),即min(R1, R2)-max(L1, L2) <= 0,则交集为空,长度为 0;
否则长度为 min(R1, R2) - max(L1, L2)

3.3 边界情况分析

  • 完全不相交:如 [0,1][4,5]max=4, min=1 → 差为负 → 取 max(0, 负数) = 0
  • 包含关系:如 [0,10][2,5]max=2, min=5 → 长度 3
  • 端点恰好相接:如 [0,3][3,7]max=3, min=3 → 长度 0。常见题目中视为无重叠(点不算长度)。
  • 左端点相等:如 [2,5][2,8]max=2, min=5 → 长度 3,正确。

3.4 极简公式的由来

利用 max(0, min(R1,R2) - max(L1,L2)) 可以一步得到非负长度。
min(R1,R2) - max(L1,L2) 为正数时即为重叠长度;为负数或零时,max(0, 值) 将输出 0。

3.5 复杂度分析

  • 时间复杂度:O(1),仅进行几次比较和加减运算。
  • 空间复杂度:O(1),只使用几个整型变量。

3.6 扩展思考

  1. 浮点数区间:若区间端点为浮点数,逻辑相同,但需考虑浮点精度。长度仍为 max(0, min(R1,R2) - max(L1,L2))
  2. 开区间或半开区间:只需根据题意调整比较符号,如半开区间 [L, R) 则重叠长度为 max(0, min(R1,R2) - max(L1,L2)) 依然适用,因为端点重合时长度为 0。
  3. 求多个区间的共同交集:可依次取 maxmin 迭代,最后若左>右则空。
  4. 区间合并:可基于排序后的区间进行合并,本题虽不涉及,但相关算法也常用 maxmin

3.7 常见错误

  • 忘记处理负数长度,直接输出 min(R1,R2) - max(L1,L2) 可能得到负值(应取与0的最大值)。
  • 混淆端点顺序,用了 min(L1,L2)max(R1,R2) 等错误组合。
  • 未考虑整数溢出(本题在 int 范围内,但若数值极大可改用 long long)。

4. 总结

区间交集长度计算是基础算法,掌握 max / min 的方法后能快速解决。本题代码极短,但背后的数学逻辑清晰,适合作为初学者理解“区间运算”的入门题。

一句话记忆:左取大,右取小,差为正,就取差,差为负,就取零。