https://ac.nowcoder.com/acm/contest/1085/A
description:
一共有n天m个安排,每个安排从l~r天,问最长的休息时间是多少
solution:
一开始想着各种数组标记,mapset乱搞,线段树,由于天数到了1e9,所以计算区间大小肯定要O1得到,正解是我们以左边界为第一关键字,右边界为第二关键字进行排序,遍历所有选项计算区间取最大值。难点就在于如何正确得到区间长度,假设当前存在一个区间l,r是有工作的,我们就有n - r (右端点到右边界) 和 l 左边界和左端点距离。
排序后设定初始的边界
我们每次只计算靠左边的距离,当所有靠左边的计算完后,就只剩下靠右边的距离n - r 对答案取max就好
其中 a[i].l - r + 1 左边界是当前的左边界 而右边界r是上次最大的r 他们之间的距离就是空闲时间
code:
#include <bits/stdc++.h> using namespace std; #define LL long long const int N = 1e5 + 50; struct node{ int l,r; }; node a[N]; bool cmp(node a,node b){ if(a.l != b.l){ return a.l < b.l; } return a.r < b.r; } int main(){ ios::sync_with_stdio(0); int n , m; cin >> n >> m; for(int i = 0;i < m;i ++){ cin >> a[i].l >> a[i].r; } sort(a ,a + m,cmp); int res = a[0].l - 1;//初始左边界到端点距离 int r = a[0].r; for(int i = 1;i < m;i ++){ if(a[i].l > r){ res = max(res,a[i].l - r + 1);// 当前左边界 - 之前最大右边界 + 1 } r = max(a[i].r,r); } res = max(res,n - r); cout << res << '\n'; return 0; }