首页 > 代码库 > vijos1788 第k大
vijos1788 第k大
可以用类似快排的快速查找算法,主要是一个分治的思想,时间复杂度为O(n)。
快排用一个中间值把序列分为两个部分,设左边部分为[l,j],右边部分为[i,r]。
(1)如果j<k,那么第k大必然是在[i,r]中,所以[l,j]的部分就不需要继续排序,递归查找[i,r]区间即可。
(2)如果k<i,那么第k大必然是在[l,j]中,所以[i,r]的部分就不需要继续排序,于是我们就递归查找[l,j]。
#include<cstdio> #include<cctype> #include<algorithm> using namespace std; inline int read(){ char c; while(c=getchar(),!isdigit(c)); int x=c-‘0‘; while(c=getchar(),isdigit(c)) x=x*10+c-‘0‘; return x; } int a[100001]; int find(int l,int r,int x){ int i=l,j=r,mid=a[l+r>>1]; while(i<=j){ while(i<r && a[i]>mid) i++; while(j>l && a[j]<mid) j--; if(i<=j) swap(a[i++],a[j--]); } if(j<x && x<i) return mid; if(x<=j) return find(l,j,x); if(x>=i) return find(i,r,x); } int main(){ int n=read(),k=read(); for(int i=1;i<=n;i+=1) a[i]=read(); printf("%d",find(1,n,k)); return 0; }
vijos1788 第k大
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。