题目链接:https://ac.nowcoder.com/acm/contest/5773/A
描述
给你一个长度为n的序列,求序列中第k小数的多少。
输入
多组输入,第一行读入一个整数T表示有T组数据。
每组数据占两行,第一行为两个整数n,k,表示数列长度和k。
第二行为n个用空格隔开的整数。t≤10,1≤n≤5×10^6,k≤n,
输出
对于每组数据,输出它的第k小数是多少。
每组数据之间用空格隔开
思路:
1.最暴力的办法就是排序后直接输出。
2.运用快速排序思想,在[L,R]中选择一个基准值,把比他大的放到左边,小的放到右边(升序),最后l==r,且为所选基准值所对应的下标,当基准值下标(从1开始)等于k时a[l]就为第k小数,因为它右边的k-1数都比他小或(虽然不一定有序);当其下标小于k时说明第k小在基准值右边因此在新区间[L,l-1]继续刚才的操作,反之当其下标大于k时说明第k小在其左边,然后在新区间[l+1,R]继续同样的操作。
#include<bits/stdc++.h>
using namespace std;
const int Ms=1e7+5;
inline int read()
{
int ans=0,f=0;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')f=!f;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
ans=ans*10+ch-'0';
ch=getchar();
}
return f?-ans:ans;
}
int ans,k;
int a[Ms];
void q_sort(int L,int R)
{
int l,r,t;
while(1)
{
l=L,r=R,t=a[L];
while(l<r)
{
while(l<r&&a[r]>t)r--;
if(l<r)a[l++]=a[r];
while(l<r&&a[l]<t)l++;
if(l<r)a[r--]=a[l];
}
a[l]=t;
if(l==k)
{
ans=a[l];
return;
}
if(l>k)R=l-1;
else L=l+1;
}
}
int main()
{
int t=read();
while(t--)
{
int n=read();
k=read();
k--;
for(int i=0;i<n;i++)a[i]=read();
f=0;
q_sort(0,n-1);
cout<<ans<<endl;
}
return 0;
}
若有什么错误,欢迎指正^ _ ^ 。