vijos1788 第k大
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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大的主要内容,如果未能解决你的问题,请参考以下文章