用c++写出一下题目代码及其注释及其算法思想:有T组数据。 每组数据给定长度为 N的数组 A,对所有长度大于等于 k 的连续的子段,取出其第 k 大放入数组 B 中。求数组 B 的第 M 大
时间: 2024-06-12 11:07:33 浏览: 46
基于C++编译原理大作业
#include <stdio.h>
#include <stdlib.h>
#define MAXN 100005
#define MAXM 1000005
int T, N, K, M;
int A[MAXN], B[MAXM];
int C[MAXM];
// 求解第 k 大的数
int kth(int l, int r, int k) {
if (l == r) return B[l];
int i = l - 1, j = r + 1, x = B[(l + r) >> 1];
while (i < j) {
while (B[++i] > x);
while (B[--j] < x);
if (i < j) {
int t = B[i]; B[i] = B[j]; B[j] = t;
}
}
if (j - l + 1 >= k) return kth(l, j, k);
else return kth(j + 1, r, k - (j - l + 1));
}
int main() {
scanf("%d", &T);
while (T--) {
scanf("%d%d%d", &N, &K, &M);
for (int i = 1; i <= N; i++) scanf("%d", &A[i]);
int cnt = 0;
for (int i = 1; i <= N - K + 1; i++) {
for (int j = i; j < i + K; j++) B[++cnt] = A[j];
C[i] = kth(cnt - K + 1, cnt, K - M + 1);
}
printf("%d\n", kth(1, N - K + 1, M));
}
return 0;
}
// 算法思想:
// 1. 对于每个长度为 k 的连续子段,将其第 k 大的数存入数组 B 中。
// 2. 对于数组 B,求解第 M 大的数。
// 3. 第 1 步可以用快排的 kth 算法实现,时间复杂度为 O(NKlogK),N 表示数组长度,K 表示子段长度。
// 4. 第 2 步可以再次使用 kth 算法求解,时间复杂度为 O(NlogN),N 表示 B 数组长度。
阅读全文