PAT B1030/A1085 完美数列
给一个整数数列和正整数p,设这个数列中最大值M,最小值m,如果有M<=m*p,则称这个数列为完美数列,给一个p和一些正整数,从里面选择尽可能多的数,使他们构成一个完美数列,并输出最多可以选择的数字个数。
分析:
从左至右扫描序列对其中的每一个数a[i]。在[i+1,n-1]二分查找第一个超过a[i]*p数的位置j,这样j-i就是对位置i来说满足a[j]<=a[i]*p的最远长度。所有j-i的最大值即为所求答案。时间复杂度为O(lnn)。
#include<cstdio> #include<algorithm> using namespace std; const int maxn = 100010; int a[maxn], n,p; //在[i+1,n-1]的范围内查找第一个大于x的位置 int binarySearch(int i,long long x) { if (a[n - 1] <= x) return n;//最大的一个元素都小于m*p,则这一整个数列就都满足。 int l = i + 1, r = n - 1,mid; while (l < r) { mid = (l + r) / 2; if (a[mid] <= x) { l = mid + 1; } else { r = mid; } } return l;//在结束时,l与r相等 } int main() { scanf("%d%d", &n, &p); for (int i = 0; i < n; i++) { scanf("%d", &a[i]); } sort(a, a + n); //递增排序 int ans = 1; //最大长度 for (int i = 0; i < n; i++) { //在a[i+1]~a[n-1],内查找第一个超过a[i]*p的数 int j = binarySearch(i, (long long)a[i] * p); ans = max(ans, j - i);//更新最大长度。 } printf("%d\n", ans); return 0; }

浙公网安备 33010602011771号