Problem L - School Reunion —— 思维

So, the alumni association of your school is arranging it’s annual reunion tomorrow. N+1
people will attend the ceremony, which includes Mr. Kashem, a notable alumnus of the
school. But he can’t stay for a long period of time, because you know, he has other
important things to do. However, Mr. Kashem wants to meet at least P​ persons. His
assistant has acquired information about tomorrow’s plan of the N​ other persons - the
time they will arrive, and the time they will exit. Now he needs to figure out the minimum
amount of time Mr. Kashem has to stay on the reunion to meet at least P​ persons. It is
obviously complicated to solve this problem by hand, and Mr. Kashem’s assistant has zero
knowledge on programming. Can you help him solving this problem?
Input Specification
First line of input contains an integer T​, indicating the number of test cases. Each test case
starts with a line containing two integers N​ and P​. Here N​ indicates the number of people
other than Mr. Kashem, who will attend the reunion. And P​ indicates the minimum number
of people Mr. Kashem wants to meet. Following N​ lines contain two integers each, st​
i​ and
en​
i​
, denoting the entry and exit time of the i​
th​ person.
Constraints
1 ≤ T ≤ 30
1 ≤ P ≤ N ≤ 100000
1 ≤ sti ≤ eni ≤ 1000000000
Use fast input method. For example, prefer using scanf to cin in C/C++.
Output Specification
For each test case, print the case number starting from 1, followed by the answer to the
case in a separate line. See sample I/O for better understanding.
Statements
Online Selection Contest, BACS Regional Programming Camp, 2018
BACS High School Programming Contest, 2018
Input Output
2
5 3
1 3
8 12
6 9
14 17
2 7
3 3
1 6
4 7
6 9
Case 1: 1
Case 2: 0

题意:

给你n个线段,让你求出最短的长度使得这个长度能穿过至少p个线段

题解:

很容易就得出一个结论:这个长度必定是在某个线段的结尾之后或者开头之前包括这个结尾或者开头。
那么我们只要遍历每一个结尾和开头就能找出答案,我们只要把结尾和开头放到两个数组里,在找结尾的时候只需要找到第一个大于他的开头,再往下找就好了,但是注意有些线段是穿过这个结尾的,那么我们就要把那些线段数量给加上去,就是lower_bound结尾,upper_bound开头,再减一减就ok了,找开头只需要把所有数对2e9反一下就好了

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pill pair<int,int>
const int N=1e5+9;

pill ed[N];
int st[N],en[N];

int main()
{
    int t;cin>>t;int ca=0;
    while(t--){
        int p,n;scanf("%d%d",&n,&p);
        for(int i=1;i<=n;i++){
            scanf("%d%d",&ed[i].first,&ed[i].second);
            st[i]=ed[i].first;
            en[i]=ed[i].second;
        }

        if(p==1){
            printf("Case %d: 0\n",++ca);
            continue;
        }

        sort(st+1,st+1+n);
        sort(en+1,en+1+n);

        int ans=2e9;

        for(int i=1;i<=n;i++){
            int pos=lower_bound(st+1,st+1+n,ed[i].second)-st;
            int need=p-1+(ed[i].first==ed[i].second?1:0);
            need-=((n-(lower_bound(en+1,en+1+n,ed[i].second)-en)+1)-(n-(upper_bound(st+1,st+1+n,ed[i].second)-st)+1));
            if(ed[i].first!=ed[i].second)need++;

            if(need<=0){ans=0;break;}

            int idx=pos+need-1;
            if(idx>n)continue;
            ans=min(ans,st[idx]-ed[i].second);
        }
        for(int i=1;i<=n;i++)
            ed[i].first=2e9-ed[i].first,ed[i].second=2e9-ed[i].second,st[i]=2e9-st[i],en[i]=2e9-en[i];
        sort(st+1,st+1+n);
        sort(en+1,en+1+n);
        for(int i=1;i<=n;i++){
            int pos=lower_bound(st+1,st+1+n,ed[i].second)-st;
            int need=p-1+(ed[i].first==ed[i].second?1:0);
            need-=((n-(lower_bound(en+1,en+1+n,ed[i].second)-en)+1)-(n-(upper_bound(st+1,st+1+n,ed[i].second)-st)+1));
            if(ed[i].first!=ed[i].second)need++;

            if(need<=0){ans=0;break;}

            int idx=pos+need-1;
            if(idx>n)continue;
            ans=min(ans,st[idx]-ed[i].second);
        }
        printf("Case %d: %d\n",++ca,ans);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值