先前接触了单调队列的题,确实是很重要的知识点,单调队列不难,就是用栈或队列来通过对队头的判断来实现队列保持单调。
题意:
给出一个大小为n的数组a[n];
求其中最大值减最小值在【m,k】中的字串最长长度。
思路:
用两个单调队列分别维护a【i】前元素中的最大值与最小值的下标,top为最值。
然后当最值之差过大时,a【i】的满足题意的最长字串为最最后操作last与【i】的距离 其中last取离i最远的一个
这样就出来了,单调队列主要是在于数组操作上,要将数组各种变量与题意紧紧联系起来。。。
代码:
#include
#include
#include
#include
using namespace std;
inline int max(int a ,int b){return a>b?a:b;}
const int N = 100010;
int s1[N],s2[N];
int a[N];
int main()
{
int n,m,k,top1,top2,last1,last2,tail1,tail2,ans;
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
memset(s1,0,sizeof(s1));
memset(s2,0,sizeof(s2));
top1=0;top2=0;tail1=0;tail2=0;ans=0;last1=0;last2=0;
for(int i=1;i<=n;i++)
{
//max
while(top1=a[i])tail2--; //top2最小元素
s2[tail2++]=i;
while(a[s1[top1]]-a[s2[top2]]>k)
{
if(s1[top1]=m)
{
ans=max(ans,i-max(last1,last2));
}
}
cout<