【问题】
大体题意是给出一个序列,求峰最多的长度为k的区间起始点和峰的数目
【思路】
这道题做了一晚上没做出来,试了好几种方法,不是超时就是wa,后来看了看题解的方法,看出这道题其实不怎么难就是实现方法难搞
前缀和,具体看代码吧
【源代码】
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
const int maxx=2e5+100;
int a[maxx],sum[maxx];
int n,k;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
sum[0]=0;
sum[n]=sum[1]=0;//初始化
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
for(int i=2; i<n; i++)//判断是否为峰值
sum[i]=(a[i]>a[i-1]&&a[i]>a[i+1]);
for(int i=1; i<=n; i++)//前缀和
sum[i]+=sum[i-1];
a[0]=a[n+1]=inf;//处理一下边界
int _max=-1,pos=0;
for(int i=1; i<=n; i++)
{
if(i+k-1>n)
break;
int cnt=sum[i+k-1]-sum[i-1];//区间内峰值的数目
//开头或者结尾,如果这个峰在区间的左右端点,就说明这个峰在这段区间中不能用,就要减去。这里是我当时没有想到的
if(a[i]>a[i-1]&&a[i]>a[i+1])
cnt--;
if(a[i+k-1]>a[i+k]&&a[i+k-1]>a[i+k-2])
cnt--;
if(cnt>_max)
_max=cnt,pos=i;
}
printf("%d %d\n",_max+1,pos);
}
return 0;
}