给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤mp,则称这个数列是完美数列。
现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列。
输入格式:
输入第一行给出两个正整数 N 和 p,其中 N(≤105)是输入的正整数的个数,p(≤109)是给定的参数。第二行给出 N 个正整数,每个数不超过 109 。
输出格式:
在一行中输出最多可以选择多少个数可以用它们组成一个完美数列。
输入样例:
10 8
2 3 20 4 5 1 6 7 8 9
输出样例:
8
思路
最后一个测试点错误是没有考虑M≤mp,p(≤109), N 个正整数,每个数不超过 109 mp可能为1018,所以p应该设成long long
关于第二个测试点运行超时,(升序排列)测试样例1 2 3 4 5 6 7 8 9 20
xx[i]=1时,xx[j]=8符合,M≤mp,ma=j-i+1=8;
则xx[i]=2时,j应该从20开始判断才数列长度可能大于8,所以j=i+ma;
AC代码
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int main(){
int n,ma=0;
long long p;
cin>>n>>p;
int xx[n];
for(int i=0;i<n;i++){
cin>>xx[i];
}
sort(xx,xx+n);//升序
for(int i=0,j;i<n;i++){
for(j=i+ma;j<n;j++){
if(xx[j]<=xx[i]*p) ma=j-i+1;
else break;
}
}
cout<<ma;
return 0;
}
超时代码
如果j是从后往前判定的,倒数第二个测试点依然超时
for(int i=0,j;i<n&&i+ma<n;i++){
for(j=n-1;j>=i+ma;j--){
if(xx[j]<=xx[i]*p) break;
}
if(j-i>ma) ma=j-i;
}
cout<<ma+1;
return 0;
}