此解与《算法笔记》中有一点点不一样,书中solve函数对每一个i在[i+1,n-1]寻找第一个大于x的数。这使得,返回的index最大为n-1,不能表达出,x>数列中所有数的情况。所以书中需要判断,数组中是否所有数均小于x,是则直接返回。
我的solve函数在区间[i+1,n]寻找第一个大于x的数,若返回的index==n,则说明,数组中是否所有数均小于x,省去判断步骤。
#include <stdio.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<cctype>
using namespace std;
const int maxn = 100005;
int n, p;
long long aa[maxn];
int solve(int i, long long x) {
//找到第一个大于a[i]*p的序号k,然后(k-1)则是最大的<=a[i]*p的序号
int left = i + 1, right = n , mid;
while (left < right) {
mid = (left + right) / 2;
if (aa[mid] > x) {
right = mid;
}
else {
left = mid + 1;
}
}
return left-1;
}
int main() {
//freopen("input.txt", "r", stdin);
cin >> n >> p;
for (int i = 0; i < n; i++) {
scanf("%lld", &aa[i]);
}
sort(aa, aa + n);
int max = 0;
for (int i = 0; i < n; i++) {
int right = solve(i, aa[i] * p);
//我们可以不写solve函数(上面一行代码不要,换下面这行),直接使用upper_bound函数
//使用方法如下:
//int right=upper_bound(aa+i+1,aa+n+1,aa[i]*p)-aa;
int length = right - i + 1;
if (max < length) {
max = length;
}
}
cout << max;
return 0;
}