題目點此跳轉
思路
題目意思是給你一個數組, 求一個最長的子區間的長度,此子區間要滿足一個條件:在此區間內的最大值與最小值的差要在[m, k]範圍內。
使用兩個單調隊列分別維護區間的最大值和最小值。
注意隊首元素出隊的條件: 當最大值的隊首減最小值的隊首不滿足題目要求時,要將兩者下標小的出隊, 才能保證區間的連續性。而出隊之前下標也要記錄一下,表示此區間開始的地方。
代碼
int n, m, k, a[maxn], ans, tmp;
int q[maxn], p[maxn], ft, rr;
int Q[maxn], P[maxn], Ft, Rr;
int main() {
while(scanf("%d%d%d", &n, &m, &k) == 3) {
for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
ft = rr = 0; Ft = Rr = 0; ans = 0; tmp = 0;
for(int i = 1; i <= n; ++i) {
while(rr > ft && q[rr-1] >= a[i]) --rr;
q[rr++] = a[i], p[rr-1] = i;
while(Rr > Ft && Q[Rr-1] <= a[i]) --Rr;
Q[Rr++] = a[i], P[Rr-1] = i;
while(Q[Ft] - q[ft] > k) {
if(P[Ft] < p[ft]) tmp = P[Ft], ++Ft;
else tmp = p[ft], ++ft;
}
if(Q[Ft]-q[ft] >= m) ans = max(ans, i-tmp);
}
printf("%d\n", ans);
}
return 0;
}