附上题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3530
这个我是看了左神的视频,学的单调队列,所布置的课后作业题目,
首先我们来看一下、要求一个区间的最大和最小的差值,而且要求在一个范围内,我们用两个队列,一个队列存储得失,字符串的上升字符列,另一个存储的是下降的字符列,所以每次比较自序列的头部,最大减去最小,就能计算出最大的差值、
因为每次都会更新、最大的差值、所以要想继续更新其他可能出现的,我们每次在不符合的情况下更新较小的下标,(最大的,更大,最小的更小,)
package HDU;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
public class HDU_3530 {
static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
public static int nextInt() throws IOException {
in.nextToken();
return (int) in.nval;
}
public static String next() throws IOException {
in.nextToken();
return (String) in.sval;
}
static int maxn = 100005;
static int num[] = new int[maxn];
static int Qmax[] = new int[maxn]; // 存储的是最大序列(下标)
static int Qmin[] = new int[maxn]; // 存储得失最小序列、(下标)
static int n, m, k; // n 个数, 不小于m, 不超过 k
public static void main(String[] args) throws IOException {
while (in.nextToken() != StreamTokenizer.TT_EOF) {
n = (int) in.nval;
m = nextInt();
k = nextInt();
int s1 = 0, e1 = 0, s2 = 0, e2 = 0, ans = 0, pos = 0;
for (int i = 1; i <= n; i++) {
num[i] = nextInt();
}
for (int i = 1; i <= n; i++) {
while (s1 < e1 && num[Qmax[e1 - 1]] < num[i]) {
e1--;
}
while (s2 < e2 && num[Qmin[e2 - 1]] > num[i]) {
e2--;
}
Qmax[e1++] = i;
Qmin[e2++] = i;
while (s1 < e1 && s2 < e2 && num[Qmax[s1]] - num[Qmin[s2]] > k) { // 大于k更新位置小的那个、这个样子使区间长度更大、
if (Qmax[s1] < Qmin[s2]) {
pos = Qmax[s1++];
} else {
pos = Qmin[s2++];
}
}
if (s1 < e1 && s2 < e2 && num[Qmax[s1]] - num[Qmin[s2]] >= m) {
ans = Math.max(ans, i - pos);
}
}
out.println(ans);
out.flush();
}
}
}