Loongint 的花篮

来源:互联网 发布:什么叫淘宝直通车 编辑:程序博客网 时间:2024/04/30 06:55

Description

Loongint 要和 MM 结婚了。在两人的走进礼堂的红地毯两侧,需要摆一些装饰用的花篮,有一些不同高度的花篮,现在这些花篮被 Loongint 依照自己的美学观念编号为S1, S2, S3 … Sn(两侧的花篮高度一样)。可 Loongint的 MM 对这些花篮的摆放方式有不同的看法,她觉得满足以下条件的花篮摆放才是最好的。如果对于区间[Si, Sj](1 ≤i<j ≤n中任意的花篮都比Si高且比Sj低,那么这个区间称为一个美学区间。对于所有的美学区间,其长度(定义为j−i)都必须小于等于k,如果有长度大于k的美学区间,MM 就会不高兴,Loongint 就会有麻烦…

Input

第一行为m。表示有m组测试数据。
对于每一组:
第一行n,k,分别表示花篮的数量和美学区间的最大长度。
第二行为n个数,分别表示S1, S2, S3 … Sn的值。

Output

如果根本不存在美学区间,输出−1。
如果存在美学区间,那么如果任意区间的长度都小于等于k,那么输出最大的长度,
否则输出最大长度比k大多少(MaxLength − k)。

Sample Input

34 25 4 3 64 16 5 4 34 21 2 3 4

Sample Output

1-11

Hint

对于30%的测试数据,1 ≤ n ≤ 100。
对于60%的测试数据,1 ≤ n ≤ 5555。
对于100%的测试数据,1 ≤ n≤ 100000, 0 < Si ≤ 100000, 1 ≤ m ≤ 3。


这道题需要采用递增栈求出当前坐标递增、递减的最长长度,不过保存坐标比较简单,

保存右边的递增的最大位置,保存左边递减的最小位置。


#include <stdio.h>#include <string.h>#define INF 0x7fffffffconst int maxn = 100005;int a[maxn], y[maxn], l[maxn], r[maxn], x[maxn];inline int Max ( int a, int b ){    return a > b ? a : b;}void print ( int n, int a[] ){    for ( int i = 0; i < n; i ++ )        printf ( "%d ", a[i] );    printf ( "\n" );}int main ( ){    int T, n, k, top, ans;    scanf ( "%d", &T );    while ( T -- )    {        memset ( l, 0, sizeof ( l ) );        memset ( r, 0, sizeof ( r ) );        memset ( x, 0, sizeof ( x ) );        scanf ( "%d%d", &n, &k );        for ( int i = 1; i <= n; i ++ )            scanf ( "%d", &a[i] );        a[0] = INF;        a[n+1] = -INF;  //为第一个赋最大值,为最后一个赋最小值,添加结束条件        ans = top = 0;        x[top] = 1;        y[top] = a[1];        for ( int i = 2; i <= n+1; i ++ )        {            while ( top >= 0 && y[top] >= a[i] )            {                r[ x[top] ] = i-1;  //表示x[top]坐标右边最多达到i-1                top --;            }            top ++;            x[top] = i;            y[top] = a[i];        }   //求出右边递增的最大坐标        top = 0;        x[top] = n;        y[top] = a[n];        for ( int i = n-1; i >= 0; i -- )        {            while ( top >= 0 && y[top] <= a[i] )            {                l[ x[top] ] = i+1;  //左边坐标最多是i+1,当前坐标不算                top --;            }            top ++;            x[top] = i;            y[top] = a[i];        }   //求出坐标递减的最小坐标        for ( int i = 1; i <= n; i ++ )        {            for ( int j = r[i]; j >= i; j -- )            //判断此区间中是否有递减坐标小于等于i            {                if ( l[j] <= i )                {                    ans = Max ( ans, j-i );                    break ;                }            }            for ( int j = l[i]; j <= i; j ++ )            {                if ( r[j] >= i )                {                    ans = Max ( ans, i-j );                    break ;                }            }        }        if ( ans == 0 )            ans = -1;        else if ( ans > k )            ans = ans-k;        printf ( "%d\n", ans );    }    return 0;}


1 0