题意:在给定的n个数中选出m个数(数的大小不超过10^9),记这m个数中的最大值为Max,最小值为Min,要求满足Max<=p*Min(p<=10^9),问所有满足条件的方案中m最大是多少。
思路:首先需要立刻反应的是,p,Min均存储为int型整数,p*Min的值可能会溢出,因此应该(long long)p*Min;然后,对于给定的序列,先从小到大排序。如下,定义指针low=0,high=n-1,maxidx=high(指向子序列的最大值)
1 2 3 4 5 6 7 8 9 20
low high/maxidx
第1次查找时(即low==0时),进入语句1,当退出while循环时,maxidx恰指向符合要求的最大值处,如下,
1 2 3 4 5 6 7 8 9 20
low maxidx high
第2,3...次查找时,根据条件Max<=p*Min,随着Min的增大,显然满足条件的最大值Max肯定在第一次指向的位置maxidx之后了,因此,从maxidx开始向右遍历,即进入语句2。
代码:
#include <cstdio> #include <algorithm> using namespace std; const int N=100005; int seq[N]; int main() { int n,p; scanf("%d%d",&n,&p); for(int i=0;i<n;i++) scanf("%d",&seq[i]); sort(seq,seq+n); int low=0,high=n-1; int maxSize=1; int maxidx=high; while(low<high){ if(low==0){ while(seq[maxidx]>(long long)seq[low]*p)//语句1 maxidx--; }else{ while(seq[maxidx]<=(long long)seq[low]*p && maxidx<=high)//语句2 maxidx++; maxidx--; } if(maxidx-low+1>maxSize) maxSize=maxidx-low+1; low++; } printf("%d",maxSize); return 0; }