题面
题解
经典贪心问题:我们按照区间的左端点排序,然后扫描一遍区间,维护区间的右端点的值val。如果当前区间的左端点大于了val,说明这两个区间就有重合的部分,然后记录一下信息,更新输出信息。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int t, n;
struct Node {
int l, r, id;
bool operator<(const Node &node) const {
return l < node.l;
}
} edge[N];
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
cin >> t;
while (t--) {
cin >> n;
for (int i = 1; i <= n; i++) {
int l, r;
cin >> l >> r;
edge[i] = {l, r, i};
}
sort(edge + 1, edge + 1 + n);
int index1 = 1, index2 = 2; //两段重复区间的编号
int pos; //记录上一段的编号
int val = -1; //边界值
int res = 0; //长度
for (int i = 1; i <= n; i++) {
int len = edge[i].r - edge[i].l;
if (val > edge[i].l) { //说明有重合,判断重合长度更新区间
len = min(len, val - edge[i].l); //防止出现第二段没有第一段长的情况
if (len > res) {
res = len;
index1 = edge[i].id;
index2 = pos;
}
}
if (edge[i].r >= val) { //第一段区间/更新边界val
val = edge[i].r;
pos = edge[i].id;
}
}
cout << res << " " << index1 << " " << index2 << endl;
}
return 0;
}