1060 爱丁顿数 (25 point(s))

英国天文学家爱丁顿很喜欢骑车。据说他为了炫耀自己的骑车功力,还定义了一个“爱丁顿数” 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

 经验总结:

首先,明确一点,爱丁顿数的意思,即满足有 E 天骑车超过 E 英里的最大整数 E,就是说超过E公里的天数X>=E,并不止是X==E,这一点明确了,剩下的就是,第四个测试点的超时问题,以及第五个测试点的关于0公里的边界处理问题了。

第四个测试点的超时问题,是因为我原本的思路,是利用flag[]数组,对于输入的公里数m,将flag[1]~flag[m-1]全部都加1,然后从N天至0天依次查询,如果flag[i]>=i,则输出i,并中断循环。但是这种思路会超时的,之后,我利用如下AC代码的思路,化解了超时问题,就是对于输入的m,只将flag[m]加1,然后从maxn-1~n-1计算所有大于n的公里的个数,之后再依次从N~0依次访问,不过每次访问判断之后,都要再加上flag[i],即公里数为i的个数。

第五个测试点关于0的处理,就很简单了,循环边界写为0再跳出就行啦~(。→‿←。)

AC代码

#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn=100010;

int main()
{
int n,m,flag[maxn];
while(~scanf("%d",&n))
{
memset(flag,0,sizeof(flag));
for(int i=0;i<n;++i)
{
scanf("%d",&m);
int lim=m<maxn-1?m:maxn-1;
++flag[lim];
}
int num=0;
for(int i=maxn-1;i>n;--i)
num+=flag[i];
for(int i=n;i>=0;--i)
{
if(num>=i)
{
printf("%d\n",i);
break;
}
num+=flag[i];
}
}
return 0;
}