题目传送门:https://www.luogu.org/problemnew/show/P1138
桶排:
对于值域在可以接受的范围内时,我们可以用不依赖比较的桶排去将数据排序。因为桶排不依赖比较排序,所以他可以打破(O(nlogn))的复杂度下界,变成(O(max-value))的,不过时间是用空间换出来的。
对于每一个值(v),我们都开一个数组(sum[v])来当做存放权值为(v)的数据的桶,最后一遍(O(maxv))的遍历就可以将数据排好序了。
对于这个题,我们只要计算出第(k)个有值的桶的下标就可以了。
时间复杂度:(O(maxv))
空间复杂度:(O(maxv))
代码如下:
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=3e4+5;
int n,k,cnt,maxv;
int a[maxn],sum[maxn];
int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
int main() {
n=read();k=read();
for(int i=1;i<=n;i++)
a[i]=read(),sum[a[i]]++,maxv=max(maxv,a[i]);//把值塞进桶子里
for(int i=1;i<=maxv;i++) {
if(sum[i])cnt++;//如果有值那么i就是第cnt小的
if(cnt==k) {printf("%d
",i);return 0;}//如果这是第k小的就直接输出
}puts("NO RESULT");//否则无解
return 0;
}