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

 

 

你可能感兴趣的:(IO)