The Treasure of The Segments CodeForces - 1462F (思维)

题目链接

题意:在坐标轴上给定n个线段,用li,ri表示左右端点,问最少删去多少个线段,才能使得剩余线段中,存在一个线段与其余线段都有交集。

分析:题目可以等价为对于每个线段求出和它没有交集的线段个数,然后取最小值就是答案。

那么对于某个线段如何求与他没有交集的线段个数呢?

线段A与线段B没有交集等价为 A的右端点在B的左端点左边,
或者 A的左端点在B的右端点的右边

所以我们可以把左/右端点拿出来存进2个数组里面排好序,
枚举每个线段再利用二分查找就可以解决了。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
const int maxn = 2e5+5;
const int mx = 40;
const int mod = 1e9+5;
const ll inf = 34359738370;
const int INF = 1e9+7;
int n;
//至少删去多少线段 才能使得剩下的线段中存在一个线段与其余线段有交集
//转化成枚举每个线段x  求出和它不相交的线段个数 取min就是答案   
//情况1:右端点在它左端点的左边  直接二分 lower_bound(r+1,r+n+1,x.first)-r-1  (相当于r数组中,值小于x.first的个数)
//情况2:左端点在它右端点的右边   n  -  (lower_bound(l+1,l+n+1,x.second+1)-l-1)(相当于l数组中,值小于等于x.second的个数)
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        pii seg[n+1];
        int l[n+1],r[n+1];
        l[0]=0,r[0]=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d %d",&seg[i].first,&seg[i].second);
            l[i]=seg[i].first,r[i]=seg[i].second;
        }
        sort(l+1,l+n+1);
        sort(r+1,r+n+1);
        int ans=n;
        for(int i=1;i<=n;i++)
        {
            pii x=seg[i];
            int v=lower_bound(l+1,l+n+1,x.second+1)-l-1;//左端点在x的右端点以及其左边的线段个数        
            int d=lower_bound(r+1,r+n+1,x.first)-r-1 + n-v;//n-v就是左端点在右边的个数了
            ans=min(ans,d);
        }
        printf("%d\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值