UJN_C++_2011 【算法分析】-【算法2.10】找出数组中的第二大元素_锦标赛算法

//
Problem E: 【算法分析】-【算法2.10】找出数组中的第二大元素
Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 18  Solved: 15
[Submit][Status][Web Board]
Description
数组有N个元素,N<=1000,应用锦标赛算法找出其中的第二大元素。


Input
输入分两行,第1行输入整数N,第2行依次输入N个整数,整数间用1个空格分开。

Output
输出只有一行,输出第二大元素。

Sample Input
10
5 3 6 8 9 0 1 2 4 7
Sample Output
8

// 	2011 Problem  E	【算法分析】-【算法2.10】找出数组中的第二大元素
#include<bits/stdc++.h>
using namespace std;

const int N=1e5+6;
int a[N];
                                        // value
void f2( int *a,int *b,int b_size,int k,int v )
{
    int k1=2*k+1;
    int k2=k1+1;

    if( k1>=b_size || k2>=b_size ) { b[k]=-1; return ; }

    if( b[k1]==v )  f2( a,b,b_size,k1,v );
    else            f2( a,b,b_size,k2,v );

    if( b[k1]<0 )
    {
        if( b[k2]>=0 )  b[k]=b[k2];
        else            b[k]=-1;
        return ;
    }
    if( b[k2]<0 )
    {
        if( b[k1]>=0 )  b[k]=b[k1];
        else            b[k]=-1;
        return ;
    }
    if( a[ b[k1] ] > a[ b[k2] ] )   b[k]=b[k1];
    else                            b[k]=b[k2];
}

void f1( int *a,int a_size )
{
    int n=1;
    while( n<a_size ) n<<=1;

    int b_size=2*n-1;
    int *b=new int[b_size];
    
    int i;
    for( i=0;i<n;i++ )
    {
        if( i<a_size )  b[ n-1+i ]=i;
        else            b[ n-1+i ]=-1;
    }
    for( i=b_size-1;i;i-=2 )
    {
        if( b[i]<0 )
        {
            if( b[i-1]>=0 )     b[ (i-1)/2 ]=b[i-1];
            else                b[ (i-1)/2 ]=-1;
        }
        else
        {
            if( a[ b[i-1] ]>a[ b[i] ] )     b[ (i-1)/2 ]=b[i-1];
            else                            b[ (i-1)/2 ]=b[i];
        }
    }
    // printf("%d\n",a[ b[0] ] );
    f2( a,b,b_size,0,b[0] );

    printf("%d\n",a[ b[0] ] );
    delete[] b;
}

int main()
{
    int n,i;
    while( ~scanf("%d",&n) )
    {
        for( i=0;i<n;i++ ) scanf("%d",&a[i]);
        f1( a,n );
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_63173957/article/details/123587322