#include<bits/stdc++.h>
using namespace std;
int main(){
long long int n,p;
scanf("%lld%lld",&n,&p);
vector<int> v(n);
for(int i=0;i<n;i++){
scanf("%d",&v[i]);
}
sort(v.begin(),v.end());
int i=0,j=0,tnum=0,maxnum=0;
/* int i=v.size()-1,j=v.size()-1,tnum=0,maxnum=0;*/
/*while(j+1>maxnum){
long long int temp=v[i]*p;
/*if(temp>=v[j]){
j--;//要找到刚好是的地方 不能再可行范围内变化,要让他从不可行,变到可行
i=0;
if(tnum>maxnum){
maxnum=tnum;
}
}*/
/* else if(temp<v[j]){
i++;
}*/
/* while(temp>=v[j]&&i>0){//不能等于0会越界
i--;
temp=v[i]*p;//引参后如果要不断变化,里面也要有参数的值 尽量让引得参是不变化的
}
tnum=j-i;
if(tnum>maxnum){
maxnum=tnum;
}//i不需要回退
j--;//方向不要改变 twopointer一旦方向改变就不容易写所以最好一开始固定 +试试此路方向会不会改变如果改变就换方向
}*/
while(n-i>maxnum){//剪枝
long long int temp=v[i]*p;
while(v[j]<=temp&&j<n){//不能跑出去凡是位置递增不能跑出数组
j++;
}
int tnum=j-i;
if(tnum>maxnum){
maxnum=tnum;
}
i++;//不管if有没有生效这一只都结束了 //没有回退是真正的two pointer
}
//固定i
printf("%d",maxnum);
return 0;
}
总结
1.two pointer 不一定非要从两头往中间靠可以只从一头走,不能有回退效率才高
2.longlong 因为数很大
3.写了从后往前,从前往后,从后往前始终有一个测试点不过,从前往后没有问题
4.引参尽量引那些不易改变的参数,改变的话要在函数内部也改变
5.题意英语中先说的谁,后面都是描述而且看清单复数
英语
问题
注意一下twopointer的小细节以及思想