题目: https://cpc.csgrandeur.cn/csgoj/problemset/problem?pid=1001
Description
在一个由N个整数组成的数列中,最多能找到多少个位置连续的整数且其中的最大值与最小值之差不超过K呢?
Input
输入包含若干组数据。每组数据的第一行有2个正整数,N(1<=N<=106),K(0<=K<=106),其中N、K的含义同上,接下来一行一共有N个32位有符号整数(32-bit signed integer),依次描绘了这个数列中各个整数的值。
Output
对于每组数据,输出一个正整数,表示在这个数列中最多能找到多少个位置连续的整数且其中的最大值与最小值之差不超过K。
Sample Input
4 2
3 1 5 2
3 2
3 1 2
Sample Output
2
3
思路:
通过单调队列去找最大值和最小值之差不小于k的连续整数
AC代码:
#include <iostream>
#include <stdio.h>
#include <queue>
#include <cmath>
using namespace std;
const int maxn = int(1e6) + 10;
int q1[maxn],q2[maxn];
int a[maxn];
inline int cmp(int x,int y,int k){
long long cx = x,cy = y,ck = k;
if(abs(cx - cy) <= ck) return 1;
else return 0;
}
int main(){
int n,k;
while(~scanf("%d%d",&n,&k)){
int ans = 1;
int front1 = 0,front2 = 0,rear1 = 1,rear2 = 1;
for(int i = 1;i<=n;i++) scanf("%d",&a[i]);
int i = 1,j = 1;
q1[0] = q2[0] = 1; //将第一个元素下标进队
while(j < n){
while(j < n && cmp(a[q1[front1]], a[q2[front2]], k)){
j++;
while(front1 < rear1 && a[j] <= a[q1[rear1-1]]) rear1--;
q1[rear1++] = j;
while(front2 < rear2 && a[j] >= a[q2[rear2-1]]) rear2--;
q2[rear2++] = j;
}
int len = j - i;
if(j == n && cmp(a[q1[front1]], a[q2[front2]], k)) len++;
ans = max(ans,len);
if(a[q1[front1]] == a[j]){
while(front1 < rear1 && !cmp(a[q1[front1]],a[q2[front2]], k)) front2++;
i = q2[front2 - 1] + 1;
}
else if(a[q2[front2]] == a[j]){
while(front2 < rear2 && !cmp(a[q2[front2]], a[q1[front1]], k)) front1++;
i = q1[front1 - 1] + 1;
}
}
printf("%d\n",ans);
}
return 0;
}