PAT 1117 C++

1.题意

E – that is, the maximum integer E such that it is for E days that one rides more than E miles.

有E天的骑行距离超过Emiles,这个E取最大整数值。

2.分析

  • 思路1
    用一个数组dis保存每天的骑行距离次数。例如,
    如果第一天骑行了2miles。那么得到结果就是dis[1]=1;
    如果第二天骑行了3miles。那么得到结果就是dis[1]=1+1,dis[2]=1 ;
    如果第三天骑行了5miles。那么得到结果就是dis[1]=1+1+1,dis[2]=1+1,dis[3]=1+1,dis[4]=1;
    这个 dis数组表示的意思就是:骑行超过i miles的天数。例如:dis[1]=3就表示骑行超过1miles有3天;dis[2]=2 就表示有2天骑行超过了2 miles

上述的代码简单明了,但是会有一个测试用例运行超时。于是有了下面这个算法

  • 思路2
    我们将骑行距离进行从大到小的排序,那么针对题目的样例输入得到的结果就是:
    6 7 6 9 3 10 8 2 7 8 => 10 9 8 8 7 7 6 6 3 2。再简单的写上下标:
0  1 2 3 4 5 6 7 8 9
10 9 8 8 7 7 6 6 3 2

再对这个10 9 8 8 7 7 6 6 3 2生成一个排序,如下所示:

index: 0  1 2 3 4 5 6 7 8 9
array:10 9 8 8 7 7 6 6 3 2
rank : 0 1 2 2 4 4 6 6 8 9

我们可以这么理解:超过10 miles的天数有0天,…超过 6 miles的天数有6天…那么针对此串输入的结果就是6。
下面给出代码的完整实现。

3.代码

#include<iostream>
#include<algorithm>
#include<functional>
#define maxn 200005
using namespace std;

int main(){
	int N;
	cin >> N;
	int i,j;
	int array[maxn];
	for(i = 0;i< N;i++){
		cin >> array[i];
	}
		
	sort(array,array+N,greater<int>());
	int anw[maxn];
	int rank = 0;
	anw[array[0]] = 0;
	for(i = 1;i< N;i++){
		if(array[i] == array[i-1]){//如果当前值和之前的值相等 
			anw[array[i]] = rank;
		}else{
			rank = i;
			anw[array[i]] = rank;
		}
	}
		
	for(j = 0;j < N ;j++){		
//		cout <<anw[array[j]]<<" "; 
		if(anw[array[j]] >= array[j]){
			cout << array[j-1] - 1;
			break;
		}
	}
	
	if(j == N){//说明没有值大于 
		cout << array[N-1]-1; 
	}
}

4.测试用例

10
6 7 6 9 3 10 8 2 7 8

10
7 7 7 9 3 10 8 2 7 8

5 
4 3 3 3 3

5 
4 3 3 2 2

5.总结

  • 数组的排序也是蛮有意思的。