题目注意点
能使选出的数个数最大的方案,一定是在该递增序列中选择连续的若干个数的方案
- 要使用LL存储数据,否则会溢出
实现
1. 二分
使用二分法查找第一个大于m*p的数,进而确定数的最大个数
#include <stdio.h>
#include <algorithm>
using namespace std;
typedef long long LL;
LL search(LL *a, LL l, LL r, LL x){
LL mid;
while (l<r){
mid=l+(r-l)/2;
if (a[mid]>x){
r=mid;
} else {
l=mid+1;
}
}
return l;
}
int main(){
LL n,p;
LL num[100010];
scanf("%lld%lld\n", &n, &p);
for (int i=0;i<n;i++){
scanf("%lld", &num[i]);
}
sort(num, num+n);
int ans=1;//最大长度,初始为1
for (int i=0;i<n;i++){
//在i~n查找第一个大于min的数
LL min=num[i];
ans=max(ans, (int)search(num, i, n, min*p)-i);//更新最大长度
}
printf("%d\n", ans);
return 0;
}
2. two pointers
此处要让两个下标都从0开始
#include <stdio.h>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 100010;
int main(){
LL n, p, num[maxn];
scanf("%lld%lld", &n, &p);
for (int i = 0; i < n; i++) {
scanf("%lld", &num[i]);
}
sort(num, num + n);
int i = 0, j = 0, ans = 0;
while (j < n) {
if (num[j] <= num[i] * p) {//满足条件时,j不断右移,直到不满足
ans = max(ans, j - i + 1);
j++;
} else {
i++;
}
}
printf("%lld\n", ans);
return 0;
}