题目描述
由于对计算机科学的热爱,以及有朝一日成为 「Bessie 博士」的诱惑,奶牛 Bessie 开始攻读计算机科学博士学位。经过一段时间的学术研究,她已经发表了 NN 篇论文(1≤N≤10^5),并且她的第 ii 篇论文得到了来自其他研究文献的 ci 次引用(0≤ci≤10^5)。
Bessie 听说学术成就可以用 h 指数来衡量。h 指数等于使得研究员有至少 h 篇引用次数不少于 h 的论文的最大整数 h。例如,如果一名研究员有 4 篇论文,引用次数分别为 (1,100,2,3),则 h 指数为 2,然而若引用次数为 (1,100,3,3) 则 h 指数将会是 3。
为了提升她的 h 指数,Bessie 计划写一篇综述,并引用一些她曾经写过的论文。由于页数限制,她至多可以在这篇综述中引用 L 篇论文(0≤L≤10^5),并且她只能引用每篇她的论文至多一次。
请帮助 Bessie 求出在写完这篇综述后她可以达到的最大 h 指数。
注意 Bessie 的导师可能会告知她纯粹为了提升 h 指数而写综述存在违反学术道德的嫌疑;我们不建议其他学者模仿 Bessie 的行为。
输入格式(从终端 / 标准输入读入):
输入的第一行包含 N 和 L。
第二行包含 N 个空格分隔的整数 c1,…,cN。
输出格式(输出至终端 / 标准输出):
输出写完综述后 Bessie 可以达到的最大 h 指数。
输入样例:
4 0 1 100 2 3
讯享网
输出样例:
讯享网2
Bessie 不能引用任何她曾经写过的论文。上文中提到,(1,100,2,3) 的 h 指数为 2。
输入样例:
4 1 1 100 2 3
输出样例:
讯享网3
如果 Bessie 引用她的第三篇论文,引用数会变为 (1,100,3,3)。上文中提到,这一引用数的 h 指数为 3。
测试点性质:
- 测试点 1-7 满足 N≤100。
- 测试点 8-10 满足 N≤1000。
- 测试点 11-17 满足 N≤10^5。
供题:Dhruv Rohatgi
题目解析:
1. 要求:给定n篇文章,求最大的h指数可能,h指数的意思是,至少有h篇文章被引用了h次及以上,可以加buff,即可以写一篇综述引用自己的文章,但是最多引用1次。
2. 思路:这道题目是要我们查找一个h值,看是否满足条件。但是当我看到n<=10^5时,内心就已经暗暗想到莫非是二分,可怖!bronze青铜的第一题就开始搞二分了?!还真是、
3. 二分一个h值,如果当前已经有大于等于h篇文章被引用大于等于h次,则说明h太小,可以增大;若当前少于h篇文章被引用h次,则数出能够引用一次就达到h次的文章数量,看是否加上这些文章能够满足h篇,若可以,则说明h可继续增大;若以上两个条件都不可以,则减小h继续尝试
知识点:
二分+贪心
//错误测试点9 //1000 1000 接下来是998、1000、以及998个999 #include <iostream> #include <cstdio> #include <algorithm> using namespace std; int quote[]; int N, L;//N篇文章,综述可引用次数L //判断当前是否能在L次引用的帮助下,存在h篇文章引用了h次以上 bool check(int h){ int cnt = 0;//统计需要增加cnt次引用,共有count篇文章满足h次引用要求 //先扫一遍,看当前是否已经有h篇文章满足引用>=h int count_1 = 0;//有count_1篇文章满足h次引用要求 int count_2 = 0;//有count_2篇文章引用了h-1次 for (int i = 1; i <= N; i++){ if (quote[i] >= h){ count_1++; } if (quote[i] == h - 1){ count_2++; } } //若已经超过h篇论文被引用了h次,则可扩大h if (count_1 >= h)return true; //若没有,再考虑是否写入综述,共有h-count_1篇需要写入综述,同时要满足有至少h-count_1篇文章可以写 if (h - count_1 <= L && count_2 >= h - count_1)return true; return false; } int main(){ // freopen("9.in", "r", stdin); cin >> N >> L; for(int i = 1; i <= N; i++){ cin >> quote[i]; } sort(quote + 1, quote + N + 1); //二分查找最大h指数 int l = 0, r = N; while(l <= r){ int mid = (l + r) / 2; // cout << " l " << l << " mid " << mid << " r " << r << endl; if (check(mid))l = mid + 1; else r = mid - 1; } cout << r; return 0; }
思考:
1. 一开始想到二分,但是忽略了只能引用一次的条件,所以陷在二分之后让哪些文章被引用的思考中
2. 跳出来之后,直接将引用次数为h-1和>=h的统计在一起,但是这样会导致超出L的限制,之后通过手动模拟给到的两个测试点中left、mid、right以及各个变量的变化情况,发现需要分步骤、分情况讨论,会更加清晰
3. 过了11个测试点之后,发现自己还有条件没有搞定,参考了一个测试点发现,不仅要判断综述可引用文章篇数与达到h指数要求的比较,还需要判断是否有那么多文章可以被引用,卡了一会
以上,草稿纸是万能的!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/127520.html