题目:在一个由N个整数组成的数列中,最多能找到多少个位置连续的整数且其中的最大值与最小值之差不超过K呢?
GDKOI 2003 又一道很类似的题(河床)使用的是动态规划,因为数据范围较小(复杂度为O(nk)),这里10^6*10^6肯定超时(确实TLE了);
这里使用一次扫描,加上单调队列,将复杂度降为O(n)(每个元素最多只进队一次,最多只出队一次),当然不是自己的思路……详见“CSU_BMW正式组建纪念赛”解题报告以及COJ1170(A Simple Problem)这两篇,LJ大牛的代码比较清晰;
WA无数次,TLE多次,RE两次,魔法值-50。。。
# include <stdio.h> # define MAXN 1000005 int n, k; int t[MAXN]; int Q[2][MAXN], f[2], r[2]; /* Q[0]:rise, Q[1]:fall */ int cmp_ll(int x, int y, int b) { long long xx = x; long long yy = y; long long bb = b; if (xx>=yy && xx-yy<=bb) return 1; if (xx<=yy && yy-xx<=bb) return 1; return 0; } int main() { int i, j, len, ans; while (~scanf("%d%d", &n, &k)) { for ( i = 1; i <= n; ++i) scanf("%d", &t[i]); f[0] = r[0] = 0; f[1] = r[1] = 0; Q[0][r[0]++] = 1; Q[1][r[1]++] = 1; ans = 1; i = j = 1; while (j < n) { while (j<n && cmp_ll(t[Q[0][f[0]]], t[Q[1][f[1]]], k)) { ++j; while (r[0]>f[0] && t[Q[0][r[0]-1]] >= t[j]) --r[0]; Q[0][r[0]++] = j; while (r[1]>f[1] && t[Q[1][r[1]-1]] <= t[j]) --r[1]; Q[1][r[1]++] = j; } len = j-i; if (j == n && cmp_ll(t[Q[0][f[0]]], t[Q[1][f[1]]], k)) ++len; if (ans < len) ans = len; if (t[Q[0][f[0]]] == t[j]) { while (f[1]<r[1] && !cmp_ll(t[Q[0][f[0]]], t[Q[1][f[1]]], k)) ++f[1]; i = Q[1][f[1]-1]+1; } else if (t[Q[1][f[1]]] == t[j]) { while (f[0]<r[0] && !cmp_ll(t[Q[0][f[0]]], t[Q[1][f[1]]], k)) ++f[0]; i = Q[0][f[0]-1]+1; } } printf("%d\n", ans); } return 0; }