一、题目
给定一个正整数数列,和正整数p,设这个数列中的最大值是M,最小值是m,如果M <= m * p,则称这个数列是完美数列。
现在给定参数p和一些正整数,请你从中选择尽可能多的数构成一个完美数列。
输入格式:
输入第一行给出两个正整数N和p,其中N(<= 10^5^)是输入的正整数的个数,p(<= 10^9^)是给定的参数。第二行给出N个正整数,每个数不超过10^9^。
输出格式:
在一行中输出最多可以选择多少个数可以用它们组成一个完美数列。
输入样例:
10 8
2 3 20 4 5 1 6 7 8 9
输出样例:
8
二、题解
在做本题目时,第一次提交的时候,第4,5个测试点不能通过。首先,第5个测试点不通过的原因是开始定义了int型,当做乘法M <= m * p的时候会超过它的范围,所以应该用long long.
另外,第四个测试点一直超时的原因是算法的时间复杂度太高,刚开始的时候,我想到了用vector里的erase函数,可是不管从第一个开始删除,还是从大到小排序后删除最后一个元素,一样的会超时,那是因为在用vector里的erase函数的时候,增加了时间的复杂度,最后,才想到了用一个变量直接处理,不满足条件直接减一!
三、代码
1 #include<iostream> 2 #include<math.h> 3 #include<algorithm> 4 #include<vector> 5 using namespace std; 6 7 bool cmp(const int &a, const int &b){ 8 return a > b; 9 } 10 11 int main(){ 12 long long N, p; 13 cin >> N >> p; 14 vector<long long>v; 15 for (int i = 0; i < N; i++){ 16 long long x; 17 cin >> x; 18 v.push_back(x); 19 } 20 sort(v.begin(), v.end(), cmp); 21 long long M = v[0]; 22 int len = v.size(); 23 for (int i = 0; i<len; i++){ 24 long long m = v[len - 1]; 25 if (sqrt(M) <= sqrt(m)*sqrt(p)) break;//使用sqrt()是为了判断M <= m * p的时候防止溢出 26 else len--; 27 } 28 cout << len << endl; 29 return 0; 30 }