解题思路:

如果我们假设有K个人,那么K就得在题目中所给的n个范围中的K个,那么,我们可以分别统计从1到n每个数在题目给的n个范围中出现的次数(即有多少人说了真话),我们设这个数组为cover,比如cover{1}代表1这个数在题目中n个范围中出现的次数。比如说我们最后求出来是k,那它对应的cover[k]就是k符合多少个范围,即有多少人说了真话,那么可以知道k=cover[k],所以我们只要求满足这个条件的所有cover的最大值。思路就是这样,那我们如何实现?第一步,如何统计。如果我们分别扫描这n个范围,再分别给这n个范围里面的数逐个加一,很容易就超时,所以要用差分法。定义一个数组cha,cha[i]=cover[i]-cover[i-1];cha[0]=cover[0];

那么cover[i]就等于cha的前i+1项和,就是从cha[0]一直加到cha[i];比如说现在有一个范围【a,b】;因为我会在处理完这n个范围后累加求cover,那我给cha[a]加上1是不是就相当于给cover[a]以及后面所有的cover都加上1,那我再给cha[b+1]减1,是不是就相当于给cover[b+1]以及后面所有的cover[i]减1,经过这两个处理,我们成功实现了给cover[a]到cover[b]加1,时间复杂度直接降为O(n);好,处理完这n个范围后我们就可以累加求cover,然后找满足cover[k]=k并且k最大的k值即可。
注意事项:当找不到满足这样的k值时候要输出-1。

参考代码:

#include<stdio.h>

int main(){

    int n;

    scanf("%d",&n);int cover[100005]={0};int cha[100005]={0};

    for(int i=0;i<n;i++){

        int a,b;

        scanf("%d %d",&a,&b);

        cha[a]+=1;cha[b+1]-=1;

    }int sum=0;int max=-1;

    for(int i=0;i<=n;i++){

        sum+=cha[i];

        cover[i]=sum;

        if(max<sum&&sum==i)max=sum;

    }

   if(max>=0)printf("%d",max);

   else{printf("-1");}

   

    return 0;

}


点赞(0)
 

0.0分

0 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论