• acwing 3745. 牛的学术圈 I(构造)


    题目传送门

    题目描述

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

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

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

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

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

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

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

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

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

    输入格式

    输入的第一行包含 NN 和 LL。

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

    输出格式

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

    数据范围

    1≤N≤1051≤N≤105,
    0≤ci≤1050≤ci≤105,
    0≤L≤1050≤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

    构造

    分析

    思想:

    • 将数组从大到小排序后,我们可以根据下标确定有多少篇引用量>=下标对应引用量: 如100 3 2 1 即 1篇>=100,2篇>=3,3篇>=2,4篇>=1 。
    • 确定边界值(有可能优化h指数的地方):边界值即 下标>下标对应引用量的第一个位置。如100 3 2 1 为i=3和100 3 3 1 为i=4。
    • 其次,我们需要确定Bessie自己写的综述产生的引用量(仅能对多个+1),加在哪一部分利于提高h指数。
    • 可以发现,提高h指数,实质是:将边界值+1以靠近下标 3篇>=2 ,而将1往边界值后的小引用量加是没有作用的(小引用量和下标的差距一定>=2),所以如果有多余的L,应该往边界值前的大引用量+1。
      重新排序后,寻找边界值,即为答案。

    作者:Lg_970
    链接:https://www.acwing.com/solution/content/101186/
    来源:AcWing
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N = 1e5 + 10;
    int n, l; 
    int c[N];
    
    bool cmp(int a, int b)
    {
        return a > b;
    }
    
    int main()
    {
        int tmp;
        int ans = 0;
        scanf("%d%d", &n, &l);
        for(int i = 1; i <= n; i++)  scanf("%d", &c[i]);
        
        sort(c+1, c+n+1, cmp);
        
        for(int i = 1; i <= n; i++)
        {
            if(i > c[i])
            {
              tmp = i;
              break;  
            } 
        }
        
        // 每个文献只能引用一次
        for(int i = tmp; i >= 1; i--)
        {
            if(l) c[i]++, l--;
        }
        
        sort(c+1, c+n+1, cmp);
        for(int i = n; i >= 1; i--)
        {
            if(i <= c[i]) 
            {
                ans = i;
                break;
            }
            
        }
        
        printf("%d\n", ans);
        return 0;
    }
    

    时间复杂度

    参考文章

  • 相关阅读:
    ZOJ 3876 May Day Holiday 蔡勒公式
    ZOJ 3870 Team Formation 贪心二进制
    ZOJ 3872 计算对答案的贡献
    Codeforces Round #324 (Div. 2)C. Marina and Vasya set
    Jquery前端分页插件pagination使用
    最简单的混合开发教程资料汇总
    最简单的混合开发教程资料汇总
    2018年各大互联网前端面试题二(滴滴打车)
    2018年各大互联网前端面试题二(滴滴打车)
    【福利】小程序开发资源干货汇总
  • 原文地址:https://www.cnblogs.com/VanHa0101/p/16016010.html
Copyright © 2020-2023  润新知