题意

本题输入一个序列,包含N个正整数,如果一个数左边的所有数都比它小、右边的所有数都比它大,那么称这个数为序列的一个“主元”。求序列中主元的个数。

思路

直接暴力判断会超时。
考虑大小的继承关系,假设序列为A,令数组leftMax记录序列A的每一位左边的最大数(含本位,下同),即leftMax[i]表示A[0] ~ A[i]的最大值,显然可以令leftMax[0] = 0。

从左到右遍历序列A,由于leftMax[i- 1]记录了A[0] ~ A[i-1]的最大值,因此如果A[i]比leftMax[i-1]大,说明leftMax[i]等于A[i];如果A[i]比leftMax[i-1]小,说明leftMax[i]等于leftMax[i-1]。

同样,令数组rightMin记录序列A的每一位右边的最小数(含本位),即rightMin[i]表示A[i+1] ~ A[n-1]的最小值,显然可以令rightMin[n] = INF (即一个很大的数)。从右到左遍历序列A,由于rightMin[i+1]记录了A[i+1] ~ A[n-1]的最小值,因此如果A[i]比rightMin[i+1]小,说明rightMin[i]等于A[i];如果A[i]比rightMin[i+1]大,说明rightMin[i]等于rightMin[i+1]。

接着就可以判断哪些是主元了。遍历序列A,如果leftMax[i-1]比A[i]小,且rightMin[i+1]比A[i]大,那么就说明A[i]是主元。全部判断完毕后进行输出即可。

const int N=1e5+10;
int a[N];
int lmax[N],rmin[N];
int n;

int main()
{
    cin>>n;

    for(int i=1;i<=n;i++) cin>>a[i];

    for(int i=1;i<=n;i++)
        lmax[i]=max(lmax[i-1],a[i]);

    rmin[n+1]=INF;
    for(int i=n;i;i--)
        rmin[i]=min(rmin[i+1],a[i]);

    vector<int> res;
    for(int i=1;i<=n;i++)
    {
        if(a[i] > lmax[i-1] && a[i] < rmin[i+1])
            res.pb(a[i]);
    }

    cout<<res.size()<<endl;
    for(int i=0;i<res.size();i++)
        if(i) cout<<' '<<res[i];
        else cout<<res[i];
    cout<<endl;

    //system("pause");
    return 0;
}