“浪潮杯”第九届山东省ACM大学生程序设计竞赛 E-Sequence

时间限制:C/C++ 5秒,其他语言10秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

We define an element  in a sequence "good", if and only if there exists  (1≤j<i) such that .

Given a permutation p of integers from 1 to n. Remove an element from the permutation such that the number of "good" elements is maximized.

输入描述:

The input consists of several test cases. The first
line of the input gives the number of test cases,.

For each test case, the first line contains an
integer ,
representing the length of the given permutation.

The second line contains n integersp1,p2,…,pn ,
representing the given permutation p.

It's guaranteed that  .

输出描述:

For each test case, output one integer in a single
line, representing the element that should be deleted. If there are several
answers, output the minimal one.

题意:给你一个长度为n(n<=1e6)的整数序列,定义“好数”:存在下标比它小的数,值也严格小于它。

你现在必须要删除且只能删除一个数,使删除后好数数量最多,如果有多个答案,输出最小的那个。

思路:只需要维护最小值和次小值,O(n)扫一遍即可。

至于为什么:因为我们为什么只需要维护最小值和次小值,是因为一个数一旦前面有超过两个比它小的数,那么只能删除该数才能使好数数量减少。(因为它本身就是一个好数)

因此定义一个权值数组c[i]表示数i删除后减少的好数的数量。

维护最小值mi和次小值mm,初始化均为inf然后每输入一个数:

1、a<mi  则mm=mi,mi=a;

2、a>=mi&&a<mm 则c[a]++,c[mi]++,mm=a;

3、a>=mm 则c[a]++;

最后找c[i]最小的i即可,多个相同的取最小的。

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1000010;
const int inf=0x3f3f3f3f;
int n,m,k;
int ans,tmp,f,mm,mi;
int a;
int c[maxn];
bool flag;
int main()
{
    int T,cas=1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        mm=inf,mi=inf;
        for(int i=1;i<=n;i++) c[i]=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a);
            if(a<=mi)
            {
                mm=mi;
                mi=a;
            }
            else if(a>=mi&&a<mm)
            {
                c[mi]++;
                c[a]++;
                mm=a;//正式赛的时候因为漏写了这一句,最后也没通过,真是日了狗了!!!
            }
            else if(a>=mm)
            {
                c[a]++;
            }
        }
        ans=inf,tmp=mi;
        for(int i=1;i<=n;i++)
        {
            if(c[i]<ans)
            {
            ans=c[i];
            tmp=i;
            }
        }
        printf("%d\n",tmp);
    }
}

猜你喜欢

转载自blog.csdn.net/lsd20164388/article/details/80377845