Dales and Hills Gym - 101411D

Problem D. Dales and Hills
Input le: dales.in
Output le: dales.out
Time limit: 2 seconds
Memory limit: 256 megabytes
Let's consider a number sequence a1; · · · ; aN . We call the continuous subsequence ai
; · · · ; aj ; · · · ; ak
(1 ≤ i < j < k ≤ N) of the sequence a hill if at < at+1 for any i ≤ t < j and at > at+1 for any j ≤ t < k.
In this case we call min{j − i; k − j} the height of the hill. Similarly, we call the continuous subsequence
a dale if at > at+1 for any i ≤ t < j and at < at+1 for any j ≤ t < k. In this case we call min{j −i; k −j}
the depth of the dale.
Compute the height of the highest hill and the depth of the deepest dale in the given sequence.
Input
The rst line of the input le contains T (1 ≤ T ≤ 100 000), the number of test cases. The test cases
follow, occupying two lines each. The rst of the two lines contains N (1 ≤ N ≤ 1 000 000), the second
the members of the sequence, separated by spaces. The sum of values of N over all test cases in the le
does not exceed 1 000 000. The absolute values of the members of the sequences do not exceed 100 000.
Output
The output le should consist of T lines and each line should contain two integers, the height of the highest
hill and the depth of the deepest dale. If there are no hills or no dales, output 0 in the corresponding
position.
Example
dales.in dales.out
2
10
4 4 1 6 3 2 1 2 5 7
10
2 3 4 5 6 7 8 9 10 9
1 3
1 0

题目大意:给出一个序列,求最高的山和最深的山谷。如果中间没有平的(a[i]==a[j]),那么必然是连续的先减后增或者先增后减。如果中间有平的地方,就重新判断是先增后减还是先减后增。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 1000005
using namespace std;
int a[maxn];
int h1,h2,h,d,d1,d2,mh,md,n,i,j,flag;//h1,h2,是山左右两边的深度,d1,d2是山谷左右两边的深度
void dale()
{
    while(a[j-1]>a[j]&&j<=n) j++;
     d1=j-i-1; 
     if(flag)
     {
         h2=j-i-1;
         h=min(h1,h2);
         mh=max(mh,h);
     }
     i=j-1;
     if(a[i]==a[j]) return ;
     while(a[j-1]<a[j]&&j<=n) j++;
         d2=h1=j-i-1; 
         i=j-1;
         d=min(d1,d2);
         md=max(md,d);
         flag=1;

}
void hill()
{
    while(a[j-1]<a[j]&&j<=n) j++;
    h1=j-i-1;
    if(flag)
    {
        d2=j-i-1;
        d=min(d1,d2);
        md=max(md,d);
    }
    i=j-1;
    if(a[i]==a[j]) return ;
    while(a[j-1]>a[j]&&j<=n) j++;
    h2=d1=j-i-1; 
    i=j-1;
    h=min(h1,h2);
    mh=max(mh,h);
    flag=1;
}
int main()
{
     //freopen("dales.in", "r", stdin);
   // freopen("dales.out", "w", stdout);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int k=1;k<=n;k++)
            scanf("%d",&a[k]);
        h1=h2=h=d1=d2=d=mh=md=0;
        i=1;j=2;
        flag=0;
        while(j<=n)
        {
            if(a[i]==a[j])
            {
                i++;
                j++;
                flag=0;
            }
            if(a[i]>a[j]) dale();
            if(a[i]<a[j]) hill();
        }
        printf("%d %d\n",mh,md);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/Twsc/p/7284493.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值