题目传送门
做法
将每个区间存下来,加两个额外区间 ( 0 , 0 ) (0, 0) (0,0) 和 ( m , m ) (m, m) (m,m),按左端点排序,判断相邻两个区间前一个区间的右端点和后一个区间的左端点是否间隔 > s > s >s(两个额外区间代表一天的最开始和一天的最结尾)。
由于区间没有重叠,所以排完序后任意一个区间的右端点都 ≤ \le ≤ 下一个区间的左端点,所以任意两个相邻区间之间都没有别的区间,所以任意两个相邻区间中间都是空闲时间。
因为每个两个不相邻区间之间都有别的区间,所以整段的空闲时间都在相邻两个区间。
所以所有的相邻区间就是所有空闲时间。加上两个额外区间是因为这样好判断开始到第一个区间和最后一个区间到结尾的情况,排序时会排到开始和结尾,不会影响别的区间的判断。
代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200010;
int n;
struct Node
{
int l, r;
}a[N];
bool cmp(Node p, Node q)
{
return p.l < q.l;
}
int main()
{
int T;
scanf("%d", &T);
while (T -- )
{
scanf("%d", &n);
int s, m;
scanf("%d%d", &s, &m);
for (int i = 1; i <= n; i ++ )
scanf("%d%d", &a[i].l, &a[i].r);
sort(a + 1, a + 1 + n, cmp);
bool success = 0;
a[n + 1].l = m;
for (int i = 1; i <= n + 1; i ++ )
if (a[i].l - a[i - 1].r >= s)
{
success = 1;
break;
}
if (success) puts("YES");
else puts("NO");
}
return 0;
}