hiho一下 第三十七周 二分查找之k小数

  题目链接: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));
}

 

posted on 2015-03-19 13:47  Vking不说话  阅读(179)  评论(0编辑  收藏  举报

导航