HDU 6276 Easy h-index(思维+二分/前缀和)
Posted chenyangxu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 6276 Easy h-index(思维+二分/前缀和)相关的知识,希望对你有一定的参考价值。
题意字面理解:求最大的h,使得至少有h篇文章被发表并且每篇文章都至少有h个引用
进一步翻译:给定一个数组,求$h_{max}$,使得$\\sum_{i=index}^{n}a_{i}\\geq h_{max}$
第一种思路,也是我一开始的思路(Onlgn):
二分答案,求$\\sum_{i=mid}^{n}a_{i}$,记为sum,记录mid,若满足sum>=h,向右区间继续二分;反之向左区间二分。
两种二分写法都可:
int get(int a[], int n)//[l, r) {int ans=0, l=0, r=n+1; while(l<r){ int mid=(r+l)>>1; if(check(a, mid)){ ans=mid;l=mid+1; } else r=mid; } return ans; }
int get(int a[], int n)//[l, r] { int ans=0, l=0, r=n; while(l<=r){ int mid=(r+l)>>1; if(check(a, mid)){ ans=mid;l=mid+1; } else r=mid-1; } return ans; }
代码:
#include <bits/stdc++.h>
using namespace std;
using namespace std;
typedef long long ll;
int n, a[200005];
int n, a[200005];
bool check(int a[], int h)
{
ll sum=0;
for(int i=h;i<=n;++i)
sum+=a[i];
return sum>=h;
}
int get(int a[], int n)
{
int ans=0, l=0, r=n;
while(l<=r){
int mid=(r+l)>>1;
if(check(a, mid)){
ans=mid;l=mid+1;
}
else r=mid-1;
}
return ans;
}
int main()
{
while(cin>>n){
for(int i=0;i<=n;++i)
cin>>a[i];
cout<<get(a, n)<<endl;
}
return 0;
}
/*
1
1 2
2
1 2 3
3
0 0 0 0
*/
{
ll sum=0;
for(int i=h;i<=n;++i)
sum+=a[i];
return sum>=h;
}
int get(int a[], int n)
{
int ans=0, l=0, r=n;
while(l<=r){
int mid=(r+l)>>1;
if(check(a, mid)){
ans=mid;l=mid+1;
}
else r=mid-1;
}
return ans;
}
int main()
{
while(cin>>n){
for(int i=0;i<=n;++i)
cin>>a[i];
cout<<get(a, n)<<endl;
}
return 0;
}
/*
1
1 2
2
1 2 3
3
0 0 0 0
*/
第二种思路,也是最简单的解法(On):
进一步翻译题目:求数组最大的下标index,使得$\\sum_{i=index}^{n}a_{i}\\geq h$,所以数组从后向前扫描,求一个前缀和即可(很简单的一个模型)
代码:
#include <bits/stdc++.h> using namespace std; int n, a[200005]; int main() { while(cin>>n){ long long int temp=0; int ans=0; for(int i=0;i<=n;++i) cin>>a[i]; for(int i=n;i>=0;--i){ temp+=a[i]; if(temp>=i) {ans=i;break;} } cout<<ans<<endl; } return 0; }
最后,记得开ll,不开ll见祖宗
以上是关于HDU 6276 Easy h-index(思维+二分/前缀和)的主要内容,如果未能解决你的问题,请参考以下文章