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 扩展思考
- 浮点数区间:若区间端点为浮点数,逻辑相同,但需考虑浮点精度。长度仍为
max(0, min(R1,R2) - max(L1,L2))。 - 开区间或半开区间:只需根据题意调整比较符号,如半开区间
[L, R)则重叠长度为max(0, min(R1,R2) - max(L1,L2))依然适用,因为端点重合时长度为 0。 - 求多个区间的共同交集:可依次取
max和min迭代,最后若左>右则空。 - 区间合并:可基于排序后的区间进行合并,本题虽不涉及,但相关算法也常用
max和min。
3.7 常见错误
- 忘记处理负数长度,直接输出
min(R1,R2) - max(L1,L2)可能得到负值(应取与0的最大值)。 - 混淆端点顺序,用了
min(L1,L2)或max(R1,R2)等错误组合。 - 未考虑整数溢出(本题在
int范围内,但若数值极大可改用long long)。
4. 总结
区间交集长度计算是基础算法,掌握 max / min 的方法后能快速解决。本题代码极短,但背后的数学逻辑清晰,适合作为初学者理解“区间运算”的入门题。
一句话记忆:左取大,右取小,差为正,就取差,差为负,就取零。