分析
比赛的时候没有看到这道题是个zz题的本质!
其实大意就是要找出一个数h,使得在K篇综述中最多引用L次论文的情况下(共K*L次),原论文中引用不少于h次的论文数量不少于h。
首先想到从小到大枚举h,对于每个h判断是否符合条件。
有几个条件,任何一次没符合条件都不行:
- 每篇论文的引用次数一定不能超过 a [ i ] + k a[i]+k a[i]+k次,因为每篇综述引用一篇论文最多一次。
- 引用次数之和不超过 K ∗ L K*L K∗L
判断的实现:从大到小排序,如果原本就大于枚举的h,就不计入综述引用次数sum。然后依次判断上面两次条件,注意累加sum。
最后发现枚举过不了,考虑二分答案h,找出最大的h。
上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
ll n,k,l;
ll a[100001];
int check(int mid)
{
ll sum=0;
for(int i=1;i<=mid;i++)
{
if(a[i]>mid) continue;
if(mid-a[i]>k) return 0;
sum+=mid-a[i];
if(sum>l*k) return 0;
}
return 1;
}
int cmp(int x,int y)
{
return x>y;
}
int main()
{
cin>>n>>k>>l;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
sort(a+1,a+n+1,cmp);
ll l=0,r=n;
while(l<=r)
{
ll mid=(l+r)/2;
if(check(mid)) l=mid+1;
else r=mid-1;
}
cout<<l-1;
return 0;
}