Given a sequence of positive integers and another positive integer p. The sequence is said to be a perfect sequence if M≤m×p where M and m are the maximum and minimum numbers in the sequence, respectively.
Now given a sequence and a parameter p, you are supposed to find from the sequence as many numbers as possible to form a perfect subsequence.
Input Specification:Each input file contains one test case. For each case, the first line contains two positive integers N and p, where N (≤105) is the number of integers in the sequence, and p (≤109) is the parameter. In the second line there are N positive integers, each is no greater than 109.
Output Specification:For each test case, print in one line the maximum number of integers that can be chosen to form a perfect subsequence.
Sample Input:10 8 2 3 20 4 5 1 6 7 8 9Sample Output:
8
测试点4运行超时,测试点5答案错误
#include#include using namespace std; int n, p; int num[100010]; int main() { scanf_s("%d %d", &n, &p); for (int i = 0; i < n; i++) { scanf_s("%d", &num[i]); } sort(num, num + n); int ans = 0; //结果 for (int i = 0; i < n; i++) { int pro = num[i] * p; int re = 0; for (int j = i; j < n; j++) { if (num[j] <= pro) { re++; } else { break; } } if (re > ans) { ans = re; } } printf("%dn", ans); }
将序列中的元素类型和p改为long long后,测试点5正确
#include#include using namespace std; int n; long long p; long long num[100010]; int main() { scanf_s("%d %lld", &n, &p); for (int i = 0; i < n; i++) { scanf_s("%lld", &num[i]); } sort(num, num + n); int ans = 0; //结果 for (int i = 0; i < n; i++) { long long pro = num[i] * p; int re = 0; for (int j = i; j < n; j++) { if (num[j] <= pro) { re++; } else { break; } } if (re > ans) { ans = re; } } printf("%dn", ans); }
将查找方法改为二分,测试点5正确
#include#include using namespace std; int n; long long p; long long num[100010]; int find(int i) { //寻找第一个大于num[i]*p的元素 long long pro = num[i] * p; if (pro >= num[n - 1]) { return n; } int left = i; int right = n - 1; int mid = 0; while (left < right) { mid = (left + right) / 2; if (num[mid] <= pro) { left = mid + 1; } else { right = mid - 1; } } return left; } int main() { scanf_s("%d %lld", &n, &p); for (int i = 0; i < n; i++) { scanf_s("%lld", &num[i]); } sort(num, num + n); int ans = 0; //结果 for (int i = 0; i < n; i++) { int j = find(i); int re = j - i; if (re > ans) { ans = re; } } printf("%dn", ans); }
find()函数的效果可由int j = upper_bound(num + i + 1, num + n, num[i] * p) - num;实现
//查找[first, last)区域中第一个大于 val 的元素。
ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last,
const T& val);
其中,first 和 last 都为正向迭代器,[first, last) 用于指定该函数的作用范围;val 用于执行目标值
同时,该函数会返回一个正向迭代器
二点法
#include#include #include using namespace std; long long n, p; long long num[100010]; int main() { scanf_s("%d %d", &n, &p); for (int i = 0; i < n; i++) { scanf_s("%d", &num[i]); } sort(num, num + n); int i = 0, j = 0; int count = 0; while (i < n && j < n) { while (j < n && num[j] <= num[i] * p) { count = max(count, j - i + 1); j++; } i++; } printf("%d", count); }



