ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

AtCoder ABC207C题解:区间相交判断与优化技巧

AtCoder ABC207C题解:区间相交判断与优化技巧

1. 题目背景与核心问题解析

ABC207C是AtCoder Beginner Contest 207的第三道题目,考察区间处理和边界条件判断能力。题目给出N个区间,每个区间可能是四种类型之一(闭区间、左闭右开、左开右闭、开区间),要求统计所有两两区间之间存在交集的组合数量。

这个问题的难点在于:

  1. 需要同时处理四种不同类型的区间表示方式
  2. 浮点数比较带来的精度问题
  3. 暴力解法O(N^2)时间复杂度在N=2000时的可行性边界

2. 标准解法思路拆解

2.1 区间统一表示法

处理多种区间类型的关键是将它们转换为统一的表示形式。推荐将原始区间[t, l, r]转换为数学上的标准区间:

  • 类型1 [t=1]: [l, r]
  • 类型2 [t=2]: [l, r)
  • 类型3 [t=3]: (l, r]
  • 类型4 [t=4]: (l, r)

实际处理时可以统一转换为双闭区间[l, r],但需要根据类型调整边界值:

def convert_interval(t, l, r): if t == 1: return (l, r) if t == 2: return (l, r - 0.1) # 右开区间处理 if t == 3: return (l + 0.1, r) # 左开区间处理 if t == 4: return (l + 0.1, r - 0.1) # 开区间处理

注意:这里使用0.1作为调整量是为了避免浮点数精度问题。实际比赛中更安全的做法是使用整数运算,将区间边界乘以10处理。

2.2 区间相交判断算法

判断两个区间[a, b]和[c, d]是否相交的条件是:

max(a, c) ≤ min(b, d)

这个条件涵盖了所有可能的相交情况,包括端点相交、包含关系等。在代码中可以这样实现:

def is_intersect(a, b, c, d): return max(a, c) <= min(b, d)

2.3 时间复杂度优化

虽然N=2000时O(N^2)的暴力解法可以通过(2000^2=4e6次操作),但仍有优化空间:

  1. 预处理所有区间的转换结果,避免重复计算
  2. 使用位运算加速比较操作
  3. 对区间进行排序后可以使用滑动窗口优化(但本题不必要)

3. 完整AC代码实现

def solve(): import sys input = sys.stdin.read data = input().split() N = int(data[0]) intervals = [] idx = 1 for _ in range(N): t = int(data[idx]) l = int(data[idx+1]) r = int(data[idx+2]) idx += 3 if t == 1: a, b = l, r elif t == 2: a, b = l, r - 0.1 elif t == 3: a, b = l + 0.1, r elif t == 4: a, b = l + 0.1, r - 0.1 intervals.append((a, b)) count = 0 for i in range(N): a1, b1 = intervals[i] for j in range(i+1, N): a2, b2 = intervals[j] if max(a1, a2) <= min(b1, b2): count += 1 print(count) solve()

4. 关键细节与注意事项

4.1 浮点数精度处理

使用浮点数处理区间边界时可能遇到精度问题,例如:

  • 3.0 - 0.1 可能得到 2.9999999999999996
  • 比较时应考虑加入微小容差epsilon

更安全的整数处理方案:

# 将区间边界乘以10处理 if t == 1: a, b = l*10, r*10 elif t == 2: a, b = l*10, r*10 -1 elif t == 3: a, b = l*10 +1, r*10 elif t == 4: a, b = l*10 +1, r*10 -1

4.2 边界条件测试用例

必须测试以下边界情况:

  1. 相同区间的不同类型表示
  2. 刚好相接但不相交的区间
  3. 包含关系的情况
  4. 大范围区间包含多个小区间

例如:

2 1 1 5 2 5 10 # 应该不相交

4.3 语言特性优化

在Python中可以使用更高效的实现方式:

  1. 使用itertools.combinations生成区间对
  2. 使用numpy数组加速计算(适用于更大数据量)
  3. 使用PyPy解释器运行可获得更好的性能

5. 算法扩展与变种

5.1 更高效率的解法

虽然O(N^2)足够通过本题,但可以考虑O(N log N)的解法:

  1. 将所有端点排序
  2. 使用扫描线算法统计重叠区间
  3. 需要特殊处理开闭区间端点

5.2 三维区间问题

如果扩展到三维空间中的长方体相交判断,原理类似:

  1. 需要在x、y、z三个维度上都满足区间相交条件
  2. 判断条件变为: max(x1,x2)≤min(x1',x2') ∧ max(y1,y2)≤min(y1',y2') ∧ max(z1,z2)≤min(z1',z2')

5.3 区间合并问题

类似题目可能要求合并所有相交的区间,这时需要:

  1. 按区间起点排序
  2. 维护当前合并区间
  3. 遍历处理每个区间决定是否合并

6. 竞赛技巧与实战经验

  1. 快速判断技巧:在纸上画出区间示意图能快速验证算法正确性
  2. 调试方法:对于WA的测试用例,打印出转换后的区间值进行验证
  3. 输入优化:在Python中使用sys.stdin.read一次性读取所有输入可以显著加快速度
  4. 常见错误:
    • 忘记处理i<j的情况导致重复计数
    • 浮点数精度处理不当
    • 区间类型判断错误

我在实际比赛中发现,这类区间问题最容易出错的就是端点处理。建议在编码前先用几个简单测试用例验证区间转换的正确性,可以节省大量调试时间。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进