P1923 【深基9.例4】求第 k 小的数

1|0做不出来根本原因在于对快速排序理解不彻底

快排代码

int randint(int l, int r){ // 生成在 [l, r] 之间的随机数 return rand() % (r - l + 1) + l; } void qsort(int l, int r){ // l 为左端点,r 为右端点 if(l >= r){ // 如果长度为 0 就返回 return; } // 给大家讲解一下为什么此时可以不用判长度为 1 的序列: // 因为序列中的这个数在添加的过程中会自动被分到 c 数组中去,而 c 在之后是不用排序的,相当于什么都没做,当然也可以在这里判一下长度为 1 的情况,直接 return 就可以了 int num = randint(l, r), ind1 = 0, ind2 = 0, ind3 = 0; // 随机选择一个数,并定义三个作为下标的变量来记录长度、存放数据 for(int i = l;i <= r;i++){ // 将 a 中的数分别分到 b, c, d(如上所述) if(a[i] < a[num]){ b[ind1++] = a[i]; } else if(a[i] == a[num]){ c[ind2++] = a[i]; } else{ d[ind3++] = a[i]; } } for(int i = 0;i < ind1;i++){ // 将 b, c, d 中的数重新放回 a a[i + l] = b[i]; } for(int i = 0;i < ind2;i++){ a[i + ind1 + l] = c[i]; } for(int i = 0;i < ind3;i++){ a[i + ind1 + ind2 + l] = d[i]; } qsort(l, l + ind1 - 1); // 继续排序原来的 b 和 d qsort(l + ind1 + ind2, r);

其实就是分治思想,把所有的区间分为左中右,小于中都去左,大于中都去右。

这题求一个数列中第k小的数完全可以用类似的思想。

/********************************************************************* 程序名: 版权: 作者: 日期: 2023-10-06 09:10 说明: *********************************************************************/ #include <iostream> using namespace std; int array[5000001], n, k; void preprocessing() { scanf("%d %d", &n, &k); for (int i = 0; i < n; i++) { scanf("%d", &array[i]); } } void solve(int l, int r) { int tl = l, tr = r, mid = array[(l + r) / 2]; do { while (array[tl] < mid) tl++; while (array[tr] > mid) tr--; if (tl <= tr) { swap(array[tl], array[tr]); tl++; tr--; } } while (tl <= tr); if (k <= tr) solve(1, tl); else if (k >= tl) solve(tl, r); else { printf("%d", array[tr + 1]); } } int main() { preprocessing(); solve(0, n - 1); return 0; }

具体思路这篇题解讲得好


__EOF__

本文作者Kdlyh
本文链接https://www.cnblogs.com/kdlyh/p/17776973.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   加固文明幻景  阅读(12)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示