寻找一个区间,满足:其中的最大值减最小值在[m,k]的范围内,输出最大的区间长度。
思路:维护2个单调队列,一个递增,一个递减。
用一个now记录现在的区间的起点,如果大的数-小的数比k还大,则可以丢弃小的那个区间,更新now。
最后的答案就是 max(ans,i-now);
#include<cstdio> #include<queue> #include<cstring> #include<algorithm> using namespace std; inline int ReadInt() { char ch = getchar(); int data = 0; while (ch < '0' || ch > '9') { ch = getchar(); } do { data = data*10 + ch-'0'; ch = getchar(); }while (ch >= '0' && ch <= '9'); return data; } int n,sma,big; inline bool isok(int x) { if(x>=sma&&x<=big) return true; return false; } int a[100005]; int main() { while(scanf("%d%d%d",&n,&sma,&big)!=EOF) { deque<int> qs; deque<int> qb; int now=0,ans=0; int flag=0; int k; for(int i=1;i<=n;i++) { a[i]=ReadInt(); } for(int i=1;i<=n;i++) { while(!qs.empty()&&a[i]<=a[qs.back()]) qs.pop_back(); qs.push_back(i); while(!qb.empty()&&a[i]>=a[qb.back()]) qb.pop_back(); qb.push_back(i); while(!qb.empty()&&!qs.empty()&&a[qb.front()]-a[qs.front()]>big) { if(qb.front()>qs.front()) { now=qs.front(); qs.pop_front(); } else { now=qb.front(); qb.pop_front(); } } if(isok(a[qb.front()]-a[qs.front()])) { ans=max(ans,i-now); } } printf("%d\n",ans); } return 0; }