牛的学术圈Ⅰ(贪心)

牛的学术圈

题目描述

由于对计算机科学的热爱,以及有朝一日成为 「Bessie 博士」的诱惑,奶牛 Bessie 开始攻读计算机科学博士学位。

经过一段时间的学术研究,她已经发表了 N 篇论文,并且她的第 i 篇论文得到了来自其他研究文献的 ci 次引用。

Bessie 听说学术成就可以用 h 指数来衡量。

h 指数等于使得研究员有至少 h 篇引用次数不少于 h 的论文的最大整数 h。

例如,如果一名研究员有 4 篇论文,引用次数分别为 (1,100,2,3),则 h 指数为 2,然而若引用次数为 (1,100,3,3) 则 h 指数将会是 3。

为了提升她的 h 指数,Bessie 计划写一篇综述,并引用一些她曾经写过的论文。

由于页数限制,她至多可以在这篇综述中引用 L 篇论文,并且她只能引用每篇她的论文至多一次。

请帮助 Bessie 求出在写完这篇综述后她可以达到的最大 h 指数。

注意 Bessie 的导师可能会告知她纯粹为了提升 h 指数而写综述存在违反学术道德的嫌疑;我们不建议其他学者模仿 Bessie 的行为。

输入格式
输入的第一行包含 N 和 L。

第二行包含 N 个空格分隔的整数 c1,…,cN。

输出格式
输出写完综述后 Bessie 可以达到的最大 h 指数。

数据范围
1≤N≤105,
0≤ci≤105,
0≤L≤105
输入样例1:

4 0
1 100 2 3

输出样例1:

2

样例1解释
Bessie 不能引用任何她曾经写过的论文。上文中提到,(1,100,2,3) 的 h 指数为 2。

输入样例2:

4 1
1 100 2 3

输出样例2:

3

如果 Bessie 引用她的第三篇论文,引用数会变为 (1,100,3,3)。上文中提到,这一引用数的 h 指数为 3。

解题思路

这道题 转换一下题意:给一个数组a[n],有N个数,用指数h,来描述数组,h代表至少有h个数大于等于h(最大的h),然后给我们一个数L,我们可以选择
最多L个数,使得每个数都加1,然后求出最大的指数h。

首先应该求出数组的指数h:
先将数组逆序,然后判断a[i]>=i是否成立,找到的最后一个满足条件的数i就是指数h
因为每一个数最多加上一,所以指数最大就是h+1(因为每个数都只能加一,
然后判断第h+1个数是否满足条件:
①但如果 第h+1个数小于h,那么它就算加上一也是小于h+1的,后面的数也一定小于h+1,所以 最大指数还是h,因为找不到h+1篇引用数大于等于h+1)所以找到h之后,终点就在于判断h+1位置的数是否大于等于h(因为指数最大是h+1,也就是前h+1个数),如果h+1位置的数小于h,那么加一之后,还是小于等于h的,并不能使指数变为h+1,后面的数比它小,也一定不可能大于h,加一也不能大于h+1
②如果 h+1位置的数大于h,那么就说明这个位置的数满足条件,但还要看看1~h+1的数有多少是等于h,这样就知道一共要加多少个一了(因为之前指数是h,所以前h个数大于等于h,但不一定大于h+1,要满足指数是h+1,那么前h+1个数必须大于等于h+1才行),最后求的个数如果大于l,就说明不存在这样的序列,反之,存在这样的序列满足条件。

代码实现

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100010;
int a[N],n,l,h;
bool cmp(int x,int y){
    return x>y;
}
int main()
{
    cin>>n>>l;
    for(int i=1;i<=n;i++) cin>>a[i];
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++){//首先,找到当前的指数h
        if(a[i]>=i) h=i;
        else break;
    }
    if(a[h+1]<h){//最大的指数如果存在,最大只能是h+1,因为每个数都只能加一,
                        //但如果第h+1个数小于h,那么它就算加上一也是小于h+1的,后面的数也一定小于h+1,
                        //所以最大指数还是h,因为找不到h+1篇引用数大于等于h+1
        cout<<h<<endl;
        return 0;
    }
    int cnt=0;
    for(int i=1;i<=h+1;i++){//如果第h+1篇 大于等于h,那么我们就能找到这样的数满足条件,
                            //然后看前面有多少个数是小于h+1的,其实就是等于h的,
                            //因为我们求出了当前指数是h,前h篇的引用数都是大于等于h的
        if(a[i]==h) cnt++;
    }
    if(cnt<=l) cout<<h+1<<endl;
    else cout<<h<<endl;//如果需要加一的数的个数大于所给的引用次数 
                            //那就无法满足h+1篇引用数大于等于h+1了,所以最大指数还是h
    return 0;
}

对数学思维不好的我来说 可真的是看了很多遍才懂题意 写下题解 希望能帮到不太能理解别的解法的你 加油呀

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值