给定一个正整数数列,和正整数 (p),设这个数列中的最大值是 (M),最小值是 (m),如果 (M≤mp),则称这个数列是完美数列。
现在给定参数 (p) 和一些正整数,请你从中选择尽可能多的数构成一个完美数列。
输入格式:
输入第一行给出两个正整数 (N) 和 (p),其中 (N)((≤10^5))是输入的正整数的个数,(p)((≤10^9))是给定的参数。第二行给出 (N) 个正整数,每个数不超过 (10^9)。
输出格式:
在一行中输出最多可以选择多少个数可以用它们组成一个完美数列。
输入样例:
10 8
2 3 20 4 5 1 6 7 8 9
输出样例:
8
题解
如果用双层循环的话,肯定是会超时的。
需要先排序。再用滑动窗口(双指针)来解决此题。
不断移动右边界。然后用左边界向右移动不断试探。并记录最大值。
示例过程如下:
1、先升序排序
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 20 |
2、两个指针 (left) 和 (right) 指向第一个数据,最大长度 (maxLen = 0)
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 20 |
---|---|---|---|---|---|---|---|---|---|
(left) (right) |
3、因为 (1 * 8 > 1),且 (1 > maxLen),所以 (maxLen = 1),(right) 右移
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 20 |
---|---|---|---|---|---|---|---|---|---|
(left) | (right) |
4、因为 (1 * 8 > 2),且 (2 > maxLen),所以 (maxLen = 2),(right) 右移
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 20 |
---|---|---|---|---|---|---|---|---|---|
(left) | (right) |
5、因为 (1 * 8 > 3),且 (3 > maxLen),所以 (maxLen = 3),(right) 右移
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 20 |
---|---|---|---|---|---|---|---|---|---|
(left) | (right) |
6、因为 (1 * 8 > 4),且 (4 > maxLen),所以 (maxLen = 4),(right) 右移
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 20 |
---|---|---|---|---|---|---|---|---|---|
(left) | (right) |
7、因为 (1 * 8 > 5),且 (5 > maxLen),所以 (maxLen = 5),(right) 右移
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 20 |
---|---|---|---|---|---|---|---|---|---|
(left) | (right) |
8、因为 (1 * 8 > 6),且 (6 > maxLen),所以 (maxLen = 6),(right) 右移
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 20 |
---|---|---|---|---|---|---|---|---|---|
(left) | (right) |
9、因为 (1 * 8 > 7),且 (7 > maxLen),所以 (maxLen = 7),(right) 右移
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 20 |
---|---|---|---|---|---|---|---|---|---|
(left) | (right) |
10、因为 (1 * 8 = 8),且 (8 > maxLen),所以 (maxLen = 8),(right) 右移
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 20 |
---|---|---|---|---|---|---|---|---|---|
(left) | (right) |
11、因为 (1 * 8 < 9),所以 (left) 右移
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 20 |
---|---|---|---|---|---|---|---|---|---|
(left) | (right) |
12、因为 (2 * 8 > 9),(right) 右移
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 20 |
---|---|---|---|---|---|---|---|---|---|
(left) | (right) |
13、因为 (2 * 8 < 20),(left) 右移
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 20 |
---|---|---|---|---|---|---|---|---|---|
(left) | (right) |
14、因为 (3 * 8 > 20),(right) 右移,(right = N),所以结束,因此最终结果是 (8)
C代码
/*********************************************************************
Score: 25
Problem: 1030
Compiler: C(gcc)
Run Time: 25ms
Version: 1.2
Author: wowpH
Date: 2019-11-22 21:38:27
From: https://www.cnblogs.com/wowpH/p/11914428.html
*********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#define MAX_N 100000
long long arr[MAX_N];// 乘法会超过int型范围
int compare(const void* a, const void* b);
int main(void) {
int N, p;
scanf("%d %d", &N, &p);
for (int i = 0; i < N; ++i) {
scanf("%lld", &arr[i]);
}
qsort(arr, N, sizeof(long long), compare);// 头文件stdlib.h
int left = 0;
int right = 0;
int maxLen = 0;
while (right < N) {
while (left < N && arr[left] * p < arr[right]) {// mp>=M
++left;
}
if (right - left + 1 > maxLen) {
maxLen = right - left + 1;
}
++right;
}
printf("%d
", maxLen);
return 0;
}
int compare(const void* a, const void* b) {
return *(int*)a - *(int*)b;// 升序
}
原文链接:https://www.cnblogs.com/wowpH/p/11914428.html