这道题乍一看,直接两个for循环就可以解决,但仔细一想,10^5的规模,很明显是会超时的,所以有什么能缩减复杂度的方法呢?因为确定了m后,就是查找相应的M,很自然的想到二分查找,这样可以降低复杂度为O(nlongn),可以通过自己写binarysearch()的方法找M,但实际上algorithm头文件下有一个upper_bound()函数可以使用,并且十分方便的找到M,问题到这里看似已经解决了,但真的submit的时候又出问题了。
问题就在a[i]和p都最大是10^9,两者相乘后的结果int绝对溢出了,所以想到用long long,但基础不扎实的人,比如我,就会直接mp=a[i]*p; 再将mp代入函数中,自以为没有问题,但提交后,最后一个测试点就是过不去,想了很久都没能解决,最后在同学(小飞侠)的提醒下想到,mp=a[i]*p; 该语句右边不强制类型转换在赋值前就已经溢出了,再往函数里加必然还是错。
除了用二分查找的方法外,还有第二种方法,就是two pointers,该方法更为简单,在下面代码的注释中给出了,这么简单的方法当然是找的题解中看到了_
using namespace std;
#include<bits/stdc++.h>
int a[100010];
int main(){
int n,p,i,j;
scanf("%d%d",&n,&p);
for(i=0;i<n;i++) scanf("%d",&a[i]);
// long long mp;
sort(a,a+n);
int ma=1;
for(i=0;i<n;i++){
// mp=(long long)a[i]*p;//一定要在右边强制类型转换否则赋值前就已经出错了
j=upper_bound(a+i+1,a+n,(long long)a[i]*p)-a;//upper_bound为自带函数
ma=max(ma,j-i);
}
/*two pointers
int i=0,j=0,ma=1;
while(i<n && j<n){
while(j<n && a[j]<=(long long)a[i]*p){
ma=max(ma,j-i+1);
j++;
}
i++;
}
*/
printf("%d",ma);
return 0;
}