PAT(B) 1030 完美数列 - C语言 - 滑动窗口 & 双指针

题目链接:1030 完美数列 (25 point(s))

给定一个正整数数列,和正整数 \(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\n", maxLen);
	return 0;
}

int compare(const void* a, const void* b) {
	return *(int*)a - *(int*)b;// 升序
}

原文链接https://www.cnblogs.com/wowpH/p/11914428.html


- End - wowpH - cnblogs -
posted @ 2019-11-22 22:53  wowpH  阅读(553)  评论(0编辑  收藏  举报