题目链接:http://hihocoder.com/contest/hiho37/problem/1 , 简单二分。
算法:
题目即为求一个无序数组数组中第k小的数,由于数据量太大,排序是会超时的。
采用提示的算法,即对于选定的Mid,以a[Mid]为支点进行一趟快排,这样比a[Mid]小的数都在Mid之前,比a[Mid]大的数在Mid之后。这时有如下三种情况:
若k<Mid,则有第k小的数一定在a[L..Mid-1]之中,令R = Mid - 1
若k=Mid,则a[Mid]就是我们要找的数
若k>Mid,则第k小的数一定在a[Mid+1..R]之中,令L = Mid + 1。此处需特别注意,在a[Mid+1..R]我们查找的k'和原来的k不相同,现在的k'=k - Mid。
这样重复LogN次之后便可找到目标数。
#include <iostream> #include <cstdio> #include <vector> #include <queue> #include <cmath> #include <string> #include <string.h> #include <algorithm> using namespace std; #define LL __int64 #define eps 1e-8 #define INF 1e8 const int maxn = 1000000 + 5; int a[maxn]; int pass(int l , int r , int m) { int i = l; int j = r; int k = a[m]; while(i != j) { while(a[j] > k && j > m) j--; a[m] = a[j]; m = j; while(a[i] < k && i < m) i++; a[m] = a[i]; m = i; } a[i] = k; return i; } int quick_sort(int l , int r , int k) { int m = (l + r) >> 1; int p = pass(l , r , m); if(k > p) { return quick_sort(p + 1 , r , k); } else if(k < p) { return quick_sort(l , p - 1 , k); } else { return a[p]; } } int main() { int n , k; scanf("%d %d" , &n , &k); for(int i = 1 ; i <= n ; i++) scanf("%d" , &a[i]); printf("%d\n" , quick_sort(1 , n , k)); }