由题目内容可知,我们要判断n个区间是否均是两两相交。
很明显,我们会想到一种情况(其实是必须是这个样子),假设我们有四个区间
如下图所示:

我们不难想到,如果我们对输入的n个区间进行排序,按照L升序排列的结果(这个结果指的是排序后的区间顺序)应该与按照R升序排列的结果一样。也就是maxL <= minR
但是,有一种情况要特判,如下图:

这种情况也满足maxL <= minR,但是maxL 和 minR来自同一个区间,我们在这里做特判就行。
以下是题解代码:
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define x first
#define y second
#define pb push_back
#define pf push_front
#define ssize(x) (int)(x.size())
#define LF "\n"
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const int N = 1e5 + 10;
const int dx[4] = { 0, 1, 0, -1 };
const int dy[4] = { 1, 0, -1, 0 };
typedef struct {
int l;
int r;
int id;
}qj;
bool isSame(qj a, qj b) {
return a.id == b.id;
}
bool cmpByL(qj a, qj b) {
if(a.l == b.l) return a.r < b.r;
return a.l < b.l;
}
bool cmpByR(qj a, qj b) {
if(a.r == b.r) return a.l < b.l;
return a.r < b.r;
}
void slove() {
int n;
cin >> n;
vector<qj> qjsA, qjsB;
for (int i = 0; i < n; i++) {
int l, r;
cin >> l >> r;
qjsA.pb({ l, r, i + 1 });
qjsB.pb({ l, r, i + 1 });
}
sort(qjsA.begin(), qjsA.end(), cmpByL);
sort(qjsB.begin(), qjsB.end(), cmpByR);
bool ABIsSame = true;
for (int i = 0; i < n; i++) {
if (!isSame(qjsA[i], qjsB[i])) {
ABIsSame = false;
break;
}
}
int MaxL = qjsA[n - 1].l;
int MinR = qjsB[0].r;
if (isSame(qjsA[n - 1], qjsB[0])) {
cout << "No" << LF;
return;
}
else if (MaxL <= MinR && ABIsSame) {
cout << "Yes" << LF;
return;
}
else {
cout << "No" << LF;
return;
}
}
int main() {
IOS;
int T = 1;
cin >> T;
while (T--) {
slove();
}
return 0;
}
说说代码思路,代码中我们创建了两个vector容器(你可以理解为动态数组),存储的内容均为n个区间,并且内容完全相同。
然后我们分别对这两个容器进行升序排序,A容器以区间的L大小进行排序,如果L相同则以R进行排序(很重要)。B容器同理,优先以R升序,R相同则以L升序。然后找出maxL和minR(最大的起点和最小的终点)。
然后就是检查排完序后的两个容器中的区间顺序是否相同,这里用一个布尔类型的变量保存结果。
这时就要进入判断部分了,我们先要判断maxL和minR是否来自同一个区间,也就是上文说的要特判的地方,然后就是判断条件maxL <= minR 和 ABIsSame是否满足。
看到这里,我必须要解释一种情况,也就是输入的所有区间都相同的情况,这个代码为什么也会输出”Yes”。

我们来看结构体qj的代码
typedef struct {
int l;
int r;
int id; //这个地方很重要
}qj;
有一个成员属性是id,用来标记此区间是第几个输入的,同时也是判断两个区间是否相同的重要变量。
bool isSame(qj a, qj b) {
return a.id == b.id;
}
我们现在来模拟一遍:
有一组完全相同的区间数据输入了程序。在输入时,程序为每个输入的区间进行了id标记。
然后就是排序,因为 sort 函数这里是稳定的,而且完全不用排序。所以这里排完序后的A、B容器里的(qj)区间元素顺序是完全相同的。
然后就来到了判断的地方:
if (isSame(qjsA[n - 1], qjsB[0])) {
cout << "No" << LF;
return;
}
else if (MaxL <= MinR && ABIsSame) {
cout << "Yes" << LF;
return;
}
else {
cout << "No" << LF;
return;
}
注意这里的isSame(qjsA[n - 1], qjsB[0])这里会返回false。
因为qjsA[n - 1], qjsB[0]这两个区间(qj)的id属性不相同。
最后,我来说说排序的问题,就拿A容器的排序来说吧。如果我们在L相同的情况下没有特殊处理。就像下面这样:
bool cmpByL(qj a, qj b) {
return a.l < b.l;
}
这样就相当于没有排序。
我们用一个样例:
1
3
1 2
1 4
1 3
如果我们排序的时候在L或者R相同的情况下没有特殊处理,就会导致排完序后的A、B中的区间顺序不相同。这里就会输出”No”。
你这个题解有问题,只是牛客测试数据太弱给你过了,你试试
1
3
1 4
2 10
3 5,你的输出是Yes,实际上区间3在区间2里面
已修改,感谢指正
还要加一个qjsA和qjsA每一位的id按顺序一一对应
其实光加这个还不行,过不了
1
3
1 2
1 4
1 3
这情况,当时还是想得太草率了。
阿巴阿巴
阿巴阿巴