#24. 区间覆盖
区间覆盖
给定 个区间 以及一个区间 ,请你选择尽量少的区间,将指定区间完全覆盖。
输出最少区间数,如果无法完全覆盖则输出 。
输入格式
第一行包含两个整数 和 ,表示给定区间的两个端点。
第二行包含整数 ,表示给定区间数。
接下来 行,每行包含两个整数 ,表示一个区间的两个端点。
输出格式
输出一个整数,表示所需最少区间数。
如果无解,则输出 。
数据范围
,
,
输入样例:
1 5
3
-1 3
2 4
3 5
输出样例:
2
下面按 k=1..25 逐组说明这套“最少区间覆盖 [s,t](无解 -1)”数据分别在卡哪些常见错误做法。
(正确贪心:按左端点排序;用指针扫所有 a_i <= cur 的区间,选其中 b 最大 的推进;若本轮无法推进则 -1。端点相接是允许覆盖的,循环通常是 while cur < t。)
- 样例:基础正确性(需要 2 段拼起来)。
- 单区间直接覆盖:答案 1;卡“总是多选/没识别已有完整覆盖”。
- 中间有空隙:应 -1;卡把“端点不连续/有 gap”当可覆盖,或错误推进导致误判有解。
- 端点相接可覆盖
[1,3] + [3,5]:应 2;卡把条件写成a < cur(不含等号)导致错判 -1。 - 起点无法覆盖(没有任何区间满足
a<=s且能推进):应 -1;卡从第一个区间开始硬推进、或忽略必须覆盖 s。 - s==t(长度 0):答案应为 0;卡仍然进入循环多选,或输出 1。
- 负数区间覆盖:卡负数排序/比较错误、或只在正数用例下写对。
- 重叠很多,必须选“能延伸最远”的:卡每次随便选第一个可用区间、或选最短/最近的导致多选甚至无解。
- 经典反例:选短的会变多:
(0,6),(0,3),(3,4),(4,10),(6,10)最优 2;卡“从能用的里选最小右端点/或选最短”导致 3。 - 乱序输入 + 有干扰区间:必须排序/指针扫描;卡按输入顺序贪心会错。
- 相同起点不同终点:必须选终点最大的那个;卡“遇到第一个就选”导致答案偏大。
- 相同终点不同起点:考察扫描范围
a<=cur的完整性;卡没把所有可用区间都比较到(漏掉更远的)。 - 极值拼接
[-1e9,0] + [0,1e9]:卡端点相接、以及极值比较/溢出(尤其用减法比较器)。 - 所有区间都在 s 左边或 t 右边:应 -1;卡误把“有区间接近”当可覆盖、或没判断覆盖起点。
- 区间远超 t:
[1,100]覆盖[1,5],答案 1;卡错误地只允许 b<=t、或强行截断导致多选/无解。 - 全靠小段链式覆盖:
[0,1],[1,2]...覆盖[0,10],答案 10;卡端点处理、循环条件、或推进写错少算/多算。 - 链式覆盖缺一段:应 -1;卡没检测“本轮无法推进”(best==cur)导致死循环或错误输出。
- 区间都在内部但到不了 t:应 -1;卡只要能推进几步就输出次数,不验证最终到达 t。
- 大量干扰区间在 [s,t] 外:正确仍可用 3 段覆盖;卡错误过滤、或把外部区间影响排序/扫描逻辑。
- 小规模随机综合:覆盖各种组合(负数、短区间、重叠/断裂);卡隐藏 bug。
- 结构化:覆盖 [0,1000] 的“固定长度 2”链:答案 500;卡性能(低效搜索)、以及端点推进/计数正确性。
- N=100000 压力:大量离散短区间,明显无解:应 -1;强卡 O(N^2) 做法、以及无解时是否能快速退出。
- N=100000 压力:全部都是超大覆盖区间:答案 1;强卡重复数据、性能、以及别输出 N。
- N=100000 压力:长度 1 的完全链覆盖 [0,100000]:答案 100000;强卡性能 + 端点相接规则 + 输出正确。
- N=100000 压力:随机短区间覆盖大区间(可能有解也可能无解,由输出文件固定):综合强测(排序、扫描、推进、性能、边界)。
如果你想专门“卡某个错误实现模板”(比如:每次选右端点最小、或没有用双指针只用堆、或把 a<=cur 写成 a<cur),把那种错误思路说一下,我可以再加几组更尖锐的针对性用例。