现在的位置: 首页 > 综合 > 正文

bnuoj 2571Sticks Problem

2018年02月22日 ⁄ 综合 ⁄ 共 1997字 ⁄ 字号 评论关闭
Xuanxuan has n sticks of different length. One day, she puts all her sticks in a line, represented by S1, S2, S3, ...Sn. After measuring the length of each stick Sk (1 <= k <= n), she finds that for some sticks
Si and Sj (1<= i < j <= n), each stick placed between Si and Sj is longer than Si but shorter than Sj. 


Now given the length of S1, S2, S3, …Sn, you are required to find the maximum value j - i.

Input

The input contains multiple test cases. Each case contains two lines. 

Line 1: a single integer n (n <= 50000), indicating the number of sticks. 

Line 2: n different positive integers (not larger than 100000), indicating the length of each stick in order.

Output

Output the maximum value j - i in a single line. If there is no such i and j, just output -1.

Sample Input

4
5 4 3 6
4
6 5 4 3

Sample Output

1
-1
题目意思:求出最长序列长度,要求在最长序列中中间的值要比这一段内最左边的值大比最右边的值要小,中间可以是无序的。最大长度大于1的则输出最大长度减1,否则输出-1.
解题:用一个结构体记录可能存在最长长度len,最两边的位置L,R和最大值的位置I。先以起点最小值开始记,每个点都要大于起点,同时记下最大值的位I,当小于起点时,也就小于当前段的起点开始的所有点值直到当前点,那么就以当前点为下一个起点开始记,作下一段。在开始计算长度时一定要注意判断条件。这一段的最大值是最右边时那么这一段可以直接与maxlen作比较。
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 50000
struct duan
{
    int L,R,len,I;//L和R为这一段的最左和右,len是这一段长度,I为这一段的最大值位置以位置小为优先
};
int cmp(duan a,duan b)
{
    return a.len>b.len;
}
int num[N+5];
int main()
{
    int n,dn,max;
    duan d[N+5];
    while(scanf("%d",&n)>0)
    {
        d[1].len=d[1].L=d[1].R=1; dn=1;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&num[i]);
            if(i==1){max=num[i];d[1].I=i;}
            else
             if(num[d[dn].L]<num[i])
              {
                  d[dn].R=i; d[dn].len=i-d[dn].L+1;
                  if(max<num[i])
                  {max=num[i]; d[dn].I=i;}
              }
              else
              {
                  dn++; d[dn].L=d[dn].R=i; d[dn].len=1;
                  max=num[i]; d[dn].I=i;
              }
        }
          sort(d+1,d+dn+1,cmp);
          int maxlen=0,tn=dn,I,tI;
        for(int i=1;i<=dn;i++)
        if(d[i].len>=2&&d[i].len-1>maxlen)
        {
            I=d[i].I;
            if(num[I]<num[d[i].R]||I==d[i].R)
            {
                if(maxlen<d[i].len-1) maxlen=d[i].len-1;
                if(i<tn) i=tn;
            }
            else
            {
                if(maxlen<I-d[i].L) maxlen=I-d[i].L;
                int j,v;
                while(maxlen<d[i].R-I-1&&d[i].R-I>=2)
                {
                    for(j=I+1;num[I]==num[j]&&j<=d[i].R;j++){ }
                    if(d[i].R-j<1||d[i].R-j<=maxlen) break;
                    max=num[j];tI=j;
                    for(v=j+1;num[j]<num[v]&&v<=d[i].R;v++)
                        if(max<num[v]){max=num[v]; tI=v;}
                        v--; I=v;
                    if(v-j>maxlen)
                    {
                        dn++; d[dn].L=j; d[dn].I=tI;
                        d[dn].R=v; d[dn].len=v-j+1;
                    }
                }
            }
        }
        printf("%d\n",maxlen>0?maxlen:(-1));
    }
}

抱歉!评论已关闭.