英国天文学家爱丁顿很喜欢骑车。据说他为了炫耀自己的骑车功力,还定义了一个“爱丁顿数”E,即满足有E天骑车超过E英里的最大整数E。据说爱丁顿自己的E等于87。
现给定某人N天的骑车距离,请你算出对应的爱丁顿数E(<=N)。
输入格式:
输入第一行给出一个正整数N(<=105),即连续骑车的天数;第二行给出N个非负整数,代表每天的骑车距离。
输出格式:
在一行中给出N天的爱丁顿数。
输入样例:10 6 7 6 9 3 10 8 2 7 8输出样例:
6
个人分析:
初做此题时,我有了一个算法,后来没有缕清关系,还是借鉴了网上的做法。今天我来做总结时,对当日的算法又做了下去,发现原来是可行的,比我借鉴的算来应该有些优势。现只对我自己的算法进行阐述,借鉴方法列出但不详细说明,可以直接看代码里的注释。
自己算法:
首先这还是可以看成一个数学题。对于n个数,找到一个数E,使得至少(这个“至少“很关键)有E个数大于E。
那么我们对给定的n个数先进行排序(从小到大)。E必定是0~N其中的一个数,假设E=i,那么说明至少有i个数大于i;
由于我们已经排序,所以必然有p[n-1],p[n-2],.......,p[n-i]大于i,即p[n-i]>i。要使得E是最大值,则在满足p[n-i]>i条件时,i应该尽可能最大。
所以,从N开始遍历,求第一个满足p[n-i]>i的i值,即为所求的E;
代码(自己的算法)
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n;
int i;
cin>>n;
int *p = new int [n];
for(i=0;i<n;i++)
cin>>p[i];
sort(p,p+n);
for(i=n;i>=0;i--)
if( p[n-i]>i )
{
cout<<i;
break;
}
return 0;
}
代码(借鉴网上的算法)
#include<iostream>
using namespace std;
int main()
{
int N;
int i;
cin>>N;
int p[200000] = {0};
for(i=0;i<N;i++)
{ int temp; cin>>temp;p[temp]++;} // p[i]表示骑i公里的天数
int sum=0;
for(i=0;i<200000;i++)
{
if(p[i] != 0)
sum += p[i]; // sum表示N天里未超过i公里的天数
// N-sum 表示N天里超过i公里的天数
if( N-sum >= i) //如果N-sum>=i,i为可能满足的E,但是要求满足条件的最大的i,需要继续往下求一步是否满足
continue;
else //如果N-sum小于i,表示i-1位满足的E
break;
}
cout<<i-1;
return 0;
}