第k小的数
Description
现有一个包含n个整数(1<=n<=900000)的无序序列(保证序列内元素各不相同),输入一个整数k(1<=k<=n),请用较快的方式找出该序列的第k小数并输出。

Input
多组输入。

首先输入一个数据组数T(1<=T<=100)

接下来是T组数据。

每组数据有两行。

第一行先输入两个整数,n和k。

接下来是一行输入n个由空格分开的互不相同的整数num(1<=num<=90000000)。

Output
对于每组数据,输出该组数据中第k小的数num。

Sample
Input
1
6 4
3 2 5 1 4 6
Output
4

思路:就是快排的思路,不过由于快排最后是一个有序的序列,那么它二分的时候左右两边都需要处理,但是对于这个题目显然只需要处理一边,所以它的时间复杂度低很多,思路就是先二分,然后选择一个数作为基准双指针扫一下,小的放他左边大的放他右边O(n),然后判断一个中间位置是否等于k,因为前面都比他小,等于直接输出就好了,不等于的话,小于k去左区间找,大于k去右区间找。
代码:

#include<iostream> 
#include<algorithm>
using namespace std;

const int maxn = 1e6 + 10;
typedef long long int ll;
ll n,k,mid;
int a[90000001];
void sloved(int l,int r){
	int temp = a[l];
	while(l < r){
		while(a[r]>temp && l<r)r--;
		a[l]=a[r];
		while(a[l]<temp && l<r)l++;
		a[r]=a[l];
	}
	a[l] = temp;
	if(l == k){
		printf("%lld\n",a[k]);
		return ;
	}
	if(l > k)  sloved(1,l-1);
	else  sloved(l+1,n);
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		scanf("%lld%lld",&n,&k);
		for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
		sloved(1,n);
	}
	return 0;
}