You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

高效求解竖线穿过最多水平线段的最大相交数问题

问题描述

给定若干由端点a到b表示的水平线段,例如(6 to 10)、(9 to 11)、(1, 20),需要编写代码找到能够穿过最多水平线段的竖线,统计该竖线穿过的线段总数量。

对于如下给出的测试用例,答案为3,即存在竖线最多可穿过3条水平线段:
测试用例示意图

测试用例输入:

6 10
10 14
1 5
8 11
13 15
10 12
12 16
2 7

求该问题的高效求解方案。

已尝试方案
  • 暴力枚举坐标法:构建覆盖所有坐标范围的数组,遍历每条线段,对线段覆盖到的所有坐标对应数组位置计数+1,最后遍历数组取最大值。该方法时间、空间复杂度随坐标范围线性增长,坐标跨度大时效率极低,还容易因数组越界触发运行时错误。
  • 端点排序差分法:将每条线段的左端点标记为+1(表示竖线过该点时新增穿过1条线段),右端点标记为-1(表示竖线过该点后减少1条穿过的线段),将所有端点按坐标排序后遍历,累加当前计数值,过程中记录的最大计数值即为结果。已编写实现代码如下:
#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
using namespace std;

int N, x, y, cnt, max_cnt = 0;
vector<pair<int, int>> end_points;

int main()
{
  cin >> N;

  for (int i = 0; i < N; i++) {
    cin >> x >> y;
    end_points.push_back(make_pair(x, 1));
    end_points.push_back(make_pair(y, -1));
  }

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

  for (const auto &e : end_points)
  {
    cnt += e.second;
    max_cnt = max(max_cnt, cnt);
  }

  cout << max_cnt;
}

代码注意点:上述实现默认按pair的默认规则排序,坐标相同时会先处理值更小的标记(即先处理-1再处理+1)。如果题目定义线段为闭区间(竖线压在线段端点上也算穿过),则需要调整排序规则,保证坐标相同的情况下+1标记排在-1标记之前,否则会出现端点处计数少算的问题。


内容的提问来源于stack exchange,提问作者Hyunseung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 09:54:31