洛谷【P1138】第k小整数

题目传送门: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\n",i);return 0;}//如果这是第k小的就直接输出
	}puts("NO RESULT");//否则无解
	return 0;
}
posted @ 2018-09-14 20:53  AKMer  阅读(318)  评论(0编辑  收藏  举报