思想:
简单的二分,但是需要区间合并优化,否则超时不对
学习:区间合并,并且这道题也要注意到是一个个离散的点,而不是线段,struct结构体排序时需要自己写一个cmp函数进行排序
代码:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5+10;
struct SEG{
int l,r;
}seg[N];
int n,len;
int L[N],R[N];
int st[N];
bool cmp(SEG A,SEG B){
if(A.l!=B.l){
return A.l<B.l;
}
else{
return A.r<B.r;
}
}
bool check(int x){
int cnt=0;
for(int i=1;i<=n;i++){
if(R[i]<=x){
++cnt;
seg[cnt].l=L[i]-(x-R[i]);
seg[cnt].r=L[i]+(x-R[i]);
}
}
sort(seg+1,seg+1+cnt,cmp);//区间合并,先排序
int last=0;//前面的线段合并后,右端点的位置
for(int i=1;i<=cnt;i++){
if(seg[i].l>last+1) return false;//因为这道题把这些管道看成了一些个点,所以即使是隔了一个位置也可以
last=max(seg[i].r,last);
}
if(last<len) return false;
return true;
}
int solve(int l,int r){
while(l<r){
int mid=(l+r)/2;
memset(st,0,sizeof st);
if(check(mid))
{
r=mid;
}
else{
l=mid+1;
}
}
return l;
}
signed main()
{
cin >> n >> len;
int cnt=0;
for(int i=1;i<=n;i++){
cin >> L[i] >> R[i];
}
int minn=0,maxn=2e9;
cout << solve(minn,maxn);
}