题目

T组数据,每次给出n(n<=1e7)个正整数,

输出从大到小第k大的数,时限1s,空间131072KB

题解

现在想想找第k大就是快排划个轴递归嘛,像线段树上二分一样

nth_element一下就好,nth_element会取出中间那个参数rank的值放在那个位置,并使左侧的比它小,右侧的比它大

在学弟的敦促下,写了一发快排的写法,只是这题由于输入数据1e7,太毒瘤了

卡掉了好几个快读的板子和快排的写法,递归快排比循环快排还是略慢一点,在快读板子的帮助下终于没T

自己写的随机取轴必被卡,实在没办法,nth_element系统优化可能有若干随机的参

代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>using namespace std;const int N=1e7+10;
int T,n,k,aa[N];struct FastIO{FILE *fp;static const int S=1e7;typedef long long ll;int wpos;char wbuf[S];FastIO():wpos(0){}inline int xchar(){static char buf[S];static int len=0,pos=0;if(pos==len)pos=0,len=fread(buf,1,S,stdin);return buf[pos++];}inline int xuint(){int c=xchar(),x=0;while(c<=32)c=xchar();for(;'0'<=c&&c<='9';c=xchar())x=x*10+c-'0';return x;}inline int xint(){int s=1,c=xchar(),x=0;while(c<=32)c=xchar();if(c=='-')s=-1,c=xchar();for(;'0'<=c&&c<='9';c=xchar())x=x*10+c-'0';return x*s;}inline void xstring(char *s){int c=xchar();while(c<=32)c=xchar();for(;c>32;c=xchar())*s++=c;*s=0;}inline void wchar(int x){if(wpos==S)fwrite(wbuf,1,S,stdout);wbuf[wpos++]=x;}inline void wint(ll x){if(x<0)wchar('-'),x=-x;char s[24];int n=0;while(x||!n)s[n++]='0'+x%10,x/=10;while(n--)wchar(s[n]);wchar('\n');}inline void wstring(const char *s){while(*s)wchar(*s++);}~FastIO(){if(wpos)fwrite(wbuf,1,wpos,stdout),wpos=0;}
}io;void sort(int l, int k, int r)
{if(l>=r)return;swap(aa[l],aa[(l+r)>>1]);int L=l,R=r-1,x=aa[l];while(L<R){while(L<R&&aa[R]>=x)R--;aa[L]=aa[R];while(L<R&&aa[L]<=x)L++;aa[R]=aa[L];}aa[L]=x;int left=L-l+1;if(left>k)sort(l,k,L);if(k>left)sort(L+1,k-left,r);
}int main()
{int T;T=io.xint();while(T--){n=io.xint(),k=io.xint();for(int i=0;i<n;++i)aa[i]=io.xint();sort(0,n+1-k,n);//nth_element(aa,aa+n-k,aa+n);io.wint(aa[n-k]);}return 0;
}

后续

思路来源

https://www.jianshu.com/p/e750b0512881

碰到一模一样的题,要确定一个2e6数组的中位数,

但是这个题交原来那个题的代码,怎么交怎么TLE,卡不过去,

于是,根据油井问题,对这个题快排部分进行了重写,

等CSU网站好了之后,打算重新交一发,看看能不能过

思路

首先,对[l,r]区间随机一个位置p,把p和l位置的数互换,防止被卡(然而实际还是被卡了)

然后用快排的思想把大于a[p]的数都放在右,小于a[p]的数都在左,

然后看p在[l,r]区间里是第几大,计左半部分(含轴)的长度为len=p-l+1

若k<=len去[l,p]里找第k大,否则去[p+1,r]里找第k-p大,期望意义O(n)

代码

#include<bits/stdc++.h>
using namespace std;
const int N=2e6+10;
typedef long long ll;
int T,n,k,x,y,a[N];
int p(int a[],int l,int r){int x=(rand()%(r-l+1))+l;swap(a[l],a[x]);int mid=a[l],i=l,j=r;while(i!=j){while(a[j]>=mid&&i<j){j--;}while(a[i]<=mid&&i<j){i++;}swap(a[i],a[j]);}a[l]=a[j];a[j]=mid;return j;
}
int qs(int a[],int l,int k,int r){if(l==r){return a[l];}int mid=p(a,l,r),len=mid-l+1;//printf("l:%d k:%d mid:%d r:%d a:%d\n",l,k,mid,r,a[mid]);if(k<=len){return qs(a,l,k,mid);}else{return qs(a,mid+1,k-len,r);}
}
int main(){srand(time(0));scanf("%d",&T);while(T--){scanf("%d%d",&n,&k);for(int i=1;i<=n;++i){scanf("%d",&a[i]);}k=(n+1)-k;//从大到小第k 是从小到大第(n+1)-kprintf("%d\n",qs(a,1,k,n));}return 0;
}

CSU - 2078 查找第k大(O(n)区间第k大 快排思想)相关推荐

  1. 寻找第K大的数(快排思想)

    使用快排思想找第K大的数,算法复杂度O(n). 1.以数组a的第0位a[0]为参考基准base,将数组划分为两个部分: 如果找第K大的数,则将大于base的数往前挪,将小于base的数往后挪.如果找第 ...

  2. 数组中最大第K元素(快排思想)

    1. 利用快排的思想找数组中最大K元素,但是找到最大K元素 是排序后的数组 地址索引为K位置上的元素 但是利用快排的思想 不需要进行排序 只需要找到 地址索引=k 位置 前k-1个元素 不一定是排序的 ...

  3. 12 | 排序(下):如何用快排思想在O(n)内查找第K大元素?

    算法对比: 算法 时间复杂度 适合场景 冒泡排序.插入排序.选择排序 O(n2) 小规模数据 归并排序.快速排序 O(nlogn) 大规模数据 归并排序和快速排序都用到了分治思想,非常巧妙.我们可以借 ...

  4. 【数据结构与算法之美】排序(下):如何用快排思想在O(n)内查找第K大元素?

    目录 一.分治思想 二.归并排序 三.快速排序 四.归并排序与快速排序的区别 五.课后思考 一.分治思想 1.分治思想:分治,顾明思意,就是分而治之,将一个大问题分解成小的子问题来解决,小的子问题解决 ...

  5. 快速排序以及基于快排思想的找前k个最大数

    快速排序是对冒泡排序的改进. 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序,它采用一种分治(Divide-and-ConquerMethod)的方法 快速排序的思想: 在数组中找 ...

  6. 寻找第K大(基于快排)

    描述 有一个整数数组,请你根据快速排序的思路,找出数组中第 k 大的数. 给定一个整数数组 a ,同时给定它的大小n和要找的 k ,请返回第 k 大的数(包括重复的元素,不用去重),保证答案存在. 要 ...

  7. 算法_第k大的数_快排(leetcode215,java)

    文章目录 前言 一.题目描述 二.思路 三.代码实现 前言 1.(Math.random()(x-y))+y // Math.random()(x-y+1)+y; 随机数x~y 2.递归 3.三目运算 ...

  8. 【LeetCode笔记】215. 数组中的第K个最大元素(Java、快排、堆排、并发快排)

    文章目录 题目描述 思路 & 代码 快排 基于 Fork / Join 的并发快排 针对 topK 的快排优化 堆排 基本堆排 结合题目的堆排 二刷 题目描述 大名鼎鼎的TOP K,主要考察排 ...

  9. 整数无序数组求第K大数(暴力|快排) - 滴滴出行2018校园招聘内推笔试-研发工程师

    时间限制:1S 空间限制:32768K 题目描述: 给定无序整数序列,求第K大的数,例如{45,67,33,21},第2大的数为45 输入描述: 输入第一行为整数序列,数字用空格分割,如:45 67 ...

最新文章

  1. 自从学了这套框架,自动化+性能都解决了
  2. 用手指触碰电子,用心灵感受震荡
  3. 【PTA 天梯赛】L2-1 分而治之(结构体存边)
  4. Ubuntu find命令详解
  5. 以下不是python文件读写方法的是-python 文件读写 - 刘江的python教程
  6. VTK修炼之道35:边缘检测_Laplace算子
  7. rsviwe32 7.6 授权_「复杂系统迁移 .NET Core平台系列」之认证和授权
  8. 插件~NuGet与packages管理项目的包包
  9. 11部高分学科纪录片,助力孩子涨姿势拓视野~
  10. aws集群重启_使用自动伸缩组在AWS中运行安全数据库集群
  11. Hive on Spark与SparkSql的区别
  12. 计算机硬件及组成原理pdf百度云,计算机组成原理整理版本.pdf
  13. java考勤表导出_考勤打卡机导出的excel考勤时间表如何生成实用的考勤表
  14. 1234的平方根用计算机怎么算,平方根计算
  15. Go微服务架构实战 中篇:6. 微服务治理策略
  16. 示例程序:关于双目视觉,标定,立体匹配(视差算法),点云,双目三维重建的原理以及代码
  17. pandas——描述性统计方法和时间类型
  18. 电厂数字化进阶之路(三):时代的召唤
  19. 虚拟机如何支持硬件虚拟化
  20. STM32基础——超声波测距+OLED显示+蜂鸣器报警

热门文章

  1. 6--目标检测和边界框和锚框
  2. 【微信小程序】uniapp开发小程序如何使用微信云托管或云函数进行云开发
  3. 基于微信云开发的商家转账至零钱
  4. 自动创建图片库、文档库
  5. 完美世界如何修改服务器ip,完美世界:完美整容及修改身材流程
  6. 虚拟资源素材商品交易平台网站源码
  7. GMS(Google Mobile Services)简介
  8. 力扣解法汇总969-煎饼排序
  9. 浩方cs全是虚拟服务器,在浩方里面的CS1.5 如何建立服务器
  10. mysql 获取农历年份_iOS 获取公历、农历日期的年月日