二分写法
#include <bits/stdc++.h>
using namespace std;
int find_upper_bound(const vector<long long>& nums, long long x)
{
int beg = 0, end = nums.size(), mid = beg + (end - beg) / 2;
while (beg < end) {
mid = beg + (end - beg) / 2;
if (nums[mid] <= x) { // 第一个大于x的数一定在mid后面
beg = mid + 1;
}
else {
end = mid; // 第一个大于x的数在mid之前(含mid)
}
}
return end; // 结束时有end=beg
}
int main()
{
#ifdef LOCAL
freopen("input.txt", "r", stdin);
#endif
int N;
long long p;
cin >> N >> p;
vector<long long> nums(N);
for (int i = 0; i < N; ++i) {
cin >> nums[i];
}
sort(nums.begin(), nums.end());
int max_contain = -1;
for (int i = 0; i < N; ++i) {
long long x = nums[i] * p;
int idx = find_upper_bound(nums, x);
max_contain = std::max(max_contain, idx - i);
}
cout << max_contain;
}
双指针(Two Pointers)
#include <bits/stdc++.h>
using namespace std;
int main()
{
#ifdef LOCAL
freopen("input.txt", "r", stdin);
#endif
int n;
long long p;
cin >> n >> p;
vector<long long> nums(n);
for (auto& i : nums) cin >> i;
sort(nums.begin(), nums.end());
// i和j起点为0,i指示最小数字,j指示最大数字
int i = 0, j = 0, ans = -1;
while (j < n) {
long long tmp = nums[i] * p;
while (j < n && nums[j] <= tmp) ++j;
ans = max(ans, j - i);
++i;
}
cout << ans;
}