1060 爱丁顿数
题目:
英国天文学家爱丁顿很喜欢骑车。据说他为了炫耀自己的骑车功力,还定义了一个“爱丁顿数” 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
思路:
1、注意E的值可能是 [0,n]区间内的任何一个数;(被这个卡了很久)
2、求有序数列第一个大于x的元素的位置 (具体参考)
代码:
#include<stdio.h> #include<iostream> #include<algorithm> using namespace std; int a[1000005]; int binary(int left, int right, int x){// 求有序数列第一个大于x的元素的位置 while(left < right){ int mid = left + (right - left) / 2; if(a[mid] > x){ right = mid; }else{ left = mid + 1; } } return left; } int main(){ int n,max=0,index; cin>>n; for(int i=0; i<n; i++){ cin>>a[i]; } sort(a,a+n); for(int i=0; i<=n; i++){ index = binary(0,n,i); if(n - index >= i && i > max){ max = i; } } cout<<max<<endl; return 0; }
另一种解法(逆序排序后直接枚举判断 思考正序排序为什么不行?)
#include <stdio.h> #include <stdlib.h> int cmp(const void *a, const void *b){ return *(int*)b - *(int*)a; } int main(){ int N, E, miles[100000]; scanf("%d", &N); for(int i = 0; i < N; i++) scanf("%d", miles + i); qsort(miles, N, sizeof(int), cmp); for(E = 0; E < N && miles[E] > E + 1; E++) ; printf("%d", E); return 0; }