问题链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805381845336064
题意:
从N个正整数中选择若干个数,使得选出的这些数中的最大值不超过最小值的p倍。问满足条件的选择方案中,选出的数的最大个数。
Note:
p与序列中的元素均可能达到10的9次方,因此a[i]*p 可能达到10的18次方,必须使用long long进行强制类型转换。
法一:二分查找
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int n, p;
int A[100010];
//binarySearch函数在[i+1,n-1]范围内查找第一个大于x的数的位置
int binarySearch(int i, long long x){
if(A[n-1] <= x)//如果所有数都不大于x,返回n
return n;
int left = i + 1, right = n - 1, mid;
while(left < right){
mid = (left + right) / 2;
if(A[mid] <= x)
left = mid + 1;
else
right = mid;
}
return left;
}
int main(){
cin >> n >> p;
for(int i = 0; i < n; i++)
cin >> A[i];
sort(A, A+n);
int ans = 1; //最大长度,初值为1(表示至少有一个数)
for(int i = 0; i < n; i++){
//在a[i+1] ~ a[n-1]中查找第一个超过a[i]*p的数,返回其位置给j
int j = binarySearch(i, (long long)A[i] * p);
ans = max(ans, j - i);//更新最大长度
}
cout << ans << endl;
return 0;
}
二分查找用upper_bound函数
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int n, p;
int A[100010];
int main(){
cin >> n >> p;
for(int i = 0; i < n; i++)
cin >> A[i];
sort(A, A+n);
int ans = 1; //最大长度,初值为1(表示至少有一个数)
for(int i = 0; i < n; i++){
//在a[i+1] ~ a[n-1]中查找第一个超过a[i]*p的数,返回其位置给j
int j = upper_bound(A + i + 1, A + n, (long long)A[i] * p) - A;
ans = max(ans, j - i);//更新最大长度
}
cout << ans << endl;
return 0;
}