整体思路:
如果不考虑L次引用原来的文献,这道题考察的就是遍历h,大于等于h的数是否有h个,取最大的h值。那么我们可以先给c数组排个序,此时c数组是降序的,如果c[h-1]>=h,那就说明满足条件,继续遍历下一个h。考虑到可以L次引用原来的文献,那么条件c[h-1]>=h就变为c[h-1]>=h-1 && c[h-1-L]>=h。依次遍历h也可以用二分或者双指针来优化。
二分法思路:
太久没用二分法了,,二分查找算法模板 - AcWing
代码:
C++:
#include<bits/stdc++.h>
using namespace std;
int N,L;
bool check(int mid,vector<int>& c){
if(mid-L-1<0){
if(c[mid-1]>=mid-1){return true;}
else{return false;}
}
if(mid==0){return true;}
if(c[mid-1]>=mid-1 && c[mid-L-1]>=mid){return true;}
return false;
}
int main(){
cin>>N>>L;
vector<int> c(N,0);
for(int i=0;i<N;i++){
scanf("%d",&c[i]);
}
sort(c.rbegin(),c.rend());
//auto max_=max_element(c.begin(),c.end());
//int temp=*max_;//最大引用次数
int l=0;
int r=N;//h的最大可能值,不考虑当前最大引用次数是因为他可能发生变化(L次引用)
//二分
while(l<r){
int mid=(l+r+1)>>1;
if(check(mid,c)){
l=mid;
}
else{
r=mid-1;
}
}
cout<<l;
return 0;
}
python:
import os
import sys
from typing import List
N,L=map(int,input().split())
c=list(map(int,input().split()))
c.sort(reverse=True)
def check(mid:int,c:List[int],L:int) -> bool:
if mid-L-1<0:
if c[mid-1]>=mid-1:
return True
else:
return False
if mid==0:
return True
if c[mid-1]>=mid-1 and c[mid-L-1]>=mid:
return True
return False
l=0
r=N
while l<r:
mid=(l+r+1)>>1
if check(mid,c,L):
l=mid
else:
r=mid-1
print(l)
注意以下四行代码:
from typing import List #def:...List[int]
N,L=map(int,input().split()) #一行输入两个数字
c=list(map(int,input().split())) #一行输入一连串数字
c.sort(reverse=True) #逆序排序
双指针法思路:
找到 c[] 数组中大于h(也就是遍历的i)的最大索引 j,说明 j 之前的论文不用再增加引用次数。如果c[i] >= i - 1 && i - j <= L,也就是前 j 项引用次数都大于等于 i,第 j+1 项到第 i 项的需要增加的引用次数小于等于L,说明这个 i 可行,就把res更新一下(res记录可行的 i)。
代码:
C++:
#include<bits/stdc++.h>
using namespace std;
int N,L;
int main(){
cin>>N>>L;
vector<int> c(N+1,0);
for(int i=1;i<=N;i++){
scanf("%d",&c[i]);
}
int res=0;
sort(c.rbegin(),c.rend()-1); //逆序排第1位~第n位
for(int i=1,j=N;i<=N;i++){
while(j && c[j]<i){j--;}
if(c[i]>=i-1 && i-j<=L){res=i;}
}
cout<<res;
return 0;
}
Python:(TLE了)
import os
import sys
from typing import List
N,L=map(int,input().split())
c=list(map(int,input().split()))
res=0
c.sort(reverse=True)
c=[0]+c
for i in range(1,N+1):
j=N
while j>0 and c[j]<i:
j-=1
if c[i]>=i-1 and i-j<=L:
res=i
print(res)