Fork me on GitHub

ACdream OJ 1099 瑶瑶的第K大 --分治+IO优化

这题其实就是一个求数组中第K大数的问题,用快速排序的思想可以解决。结果一路超时。。原来要加输入输出优化,具体优化见代码。

顺便把求数组中第K大数和求数组中第K小数的求法给出来。

代码:

/*
* this code is made by whatbeg
* Problem: 1099
* Verdict: Accepted
* Submission Date: 2014-06-15 00:13:53
* Time: 4340 MS
* Memory: 21212 KB
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <iomanip>
using namespace std;
#define N 1007

//复杂度O(n)
int Max_K(int a[],int low,int high,int k)
{
    if(k <= 0 || k > high-low+1)
        return -1;
    int flag = low + abs(rand())%(high-low+1);  //随机选择一个基准点
    swap(a[low],a[flag]);
    int mid = low;
    int cnt = 1;
    for(int i=low+1;i<=high;i++)
    {
        if(a[i] > a[low])   //遍历,把较大的数放在数组左边
        {
            swap(a[++mid],a[i]);
            cnt++;
        }
    }
    //比基准点大的数的个数为cnt-1
    swap(a[mid],a[low]);    //将基准点放在左、右两部分的分界处
    if(cnt > k)
        return Max_K(a,low,mid-1,k);
    else if(cnt < k)
        return Max_K(a,mid+1,high,k-cnt);
    else
        return mid;
}
 
int Min_K(int a[],int low,int high,int k)
{
    if(k <= 0 || k > high-low+1)
        return -1;
    int flag = low + abs(rand())%(high-low+1);
    swap(a[low],a[flag]);
    int mid = low;
    int cnt = 1;
    for(int i=low+1;i<=high;i++)
    {
        if(a[i] < a[low])
        {
            swap(a[++mid],a[i]);
            cnt++;
        }
    }
    swap(a[mid],a[low]);
    if(k < cnt)
        return Min_K(a,low,mid-1,k);
    else if(k > cnt)
        return Min_K(a,mid+1,high,k);
    else
        return mid;
}
 
inline int in()
{
    char ch;
    int a = 0;
    while((ch = getchar()) == ' ' || ch == '\n');
    a += ch - '0';
    while((ch = getchar()) != ' ' && ch != '\n')
    {
        a *= 10;
        a += ch - '0';
    }
    return a;
}
 
inline void out(int a)
{
    if(a >= 10)
        out(a / 10);
    putchar(a % 10 + '0');
}
 
int a[5000006];
 
int main()
{
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        getchar();
        for(int i=0;i<n;i++)
            a[i] = in();
        int res = Max_K(a,0,n-1,k);
        out(a[res]);
        puts("");
    }
    return 0;
}
View Code

 

 

posted @ 2014-06-15 00:24  whatbeg  阅读(604)  评论(0编辑  收藏  举报