6.24 区间合并

这部分比较简单
题目:

https://www.acwing.com/problem/content/1345/
https://www.acwing.com/problem/content/424/
二分和区间和并结合:

https://www.acwing.com/problem/content/5410/

#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int N = 1e5 + 10;
typedef long long LL;
typedef pair<int, int> PII;
PII a[N];
int n, len;
// 需要吧中间时刻转化为时刻用到
bool check(LL mid){
    vector<PII> segs;
    //得到两者的区间位置
    for(int i=0;i<n;i++){
        int l = a[i].first, s = a[i].second;
        if(s<=mid){
        int left = max(1ll, l - mid + s), right = min((LL)len, l + mid - s);
            segs.push_back({left,right});
        }
    }
    int cnt = segs.size();
    sort(segs.begin(), segs.end()); // 按左端点从小到大排序
    
    if(segs.empty()) return false;
    if(segs[0].first > 1) return false;
    int dr = segs[0].second;
    // 判断在不在管道内
    for(int i=1;i<cnt;i++){
        // 判断是否只有一个区间
        if(segs[i].first > dr + 1) return false;
        dr = max(dr, segs[i].second);
    }
    return dr == len;
}
int main(){
     scanf("%d%d", &n, &len);

    for(int i = 0; i < n; i ++) 
    {
        int l, s;
        scanf("%d%d", &l, &s);
        a[i] = {l, s};
    }
    LL l=1,r = 2e9;
    // 二分法 二分的是可满足的时刻;
    while(r>l){
        LL mid = l + r >> 1; // 相加过程中可能会爆int,记得要开long long
        if( check(mid) ) r = mid;
        else l = mid + 1;
    }
    printf("%lld",l);
    return 0;
}
posted @   yyyne  阅读(7)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起