NC207028 第k小数

题目

题目描述

给你一个长度为 n 的序列,求序列中第 k 小数的多少。

输入描述

多组输入,第一行读入一个整数 T 表示有 T 组数据。
每组数据占两行,第一行为两个整数 n,k ,表示数列长度和 k
第二行为 n 个用空格隔开的整数。

输出描述

对于每组数据,输出它的第 k 小数是多少。
每组数据之间用空格隔开

示例1

输入

2
5 2
1 4 2 3 4
3 3
3 2 1

输出

2
3

备注

t10,1n5×106,kn 数列里每个数都在 int 范围内

题解

知识点:排序,递归。

数据量显然使用 O(nlogn) 的排序,但是使用快排可以更加优化。

快排的原理是选定一个数值(一定是值,不是下标,因为不是按下标分界,是按值分界)作为枢轴 mid ,然后设置两个指针 i,j 同时从首尾开始遍历序列,i 找小于 mid 的元素, j 找大于 mid 的元素。每找到一组就交换它们,直到 i>j,最后序列就排序为左右部分,左边比 mid 小且 j 是右端点,右边比 mid 大且 i 是左端点。

观察 ki,j 的关系,若 kj 则第 k 小在左边,接下来只要排左边;若 ki 则第 k 小在右边,接下来只要排右边;若 i<k<j (仅在 ij 同时到达值为 mid 的位置才可能出现,其他情况 j=i1 ),则目前第 k 个就是最终答案。

快读快写是题目要求 qwq。

时间复杂度 O(nlogn)

空间复杂度 O(n)

代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a[5000007];
inline int read() {
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c>'9') {
if (c == '-') f = -1;
c = getchar();
}///整数符号
while (c >= '0' && c <= '9') {
x = (x << 3) + (x << 1) + (c ^ 48);
c = getchar();
}///挪位加数
return x * f;
}
int quick_sort(int l, int r, int k) {
if (l == r) return a[l];
int i = l, j = r;
int mid = a[l + r >> 1];
while (i <= j) {
while (a[i] < mid)i++;
while (a[j] > mid)j--;
if (i <= j) {
swap(a[i], a[j]);
i++, j--;
}
}///循环条件设成包括=,是为了循环完的i,j就是需要排序的严格端点。
if (k <= j) return quick_sort(l, j, k);///因为只有在(j,i)之间才是以及排好的,不包括端点
else if (k >= i) return quick_sort(i, r, k);
else return a[k];
}
bool solve() {
int n = read(), k = read();
for (int i = 0;i < n;i++) a[i] = read();
cout << quick_sort(0, n - 1, k - 1) << '\n';
return true;
}
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
t = read();
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}
posted @   空白菌  阅读(110)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示