POJ 2823 Sliding Window 单调队列
题意很明显,注意用C++提交,不然会超时。
说说我对单调队列的理解吧。
其实就是每次都在队头保留了ans。就是每次你想知道第i个位置的答案,每次取出队头元素就OK了。
然后就是怎么维护了。
例如要求最大值,那么,队头应该是一个最大值的。所以这个队列是单调递减的,每次插入a[i]的时候,维护它单调递减就OK,同时可以把它插入的这个位置后面的值删除了,是没用了。因为a[i]比他们大,而且比他们新。
关键就是这个新了。
应该这些元素不在这个窗口的话,那些就属于废弃元素,废弃元素不能被选择,所以队列有第二个参数。id。保留队头元素在数组a[i]的pos。那么当对头的id == i - k的时候。它就是废弃的了。然后把head++即可。
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> int n,k; const int maxn = 1e6 + 20; int a[maxn]; struct node { int val,id; node () {} node (int vv,int ii) : val(vv), id(ii) {} }que[maxn]; int ans_min[maxn]; int ans_max[maxn]; void work () { int lenmin = 0, lenmax = 0; scanf ("%d%d", &n, &k); for (int i = 1; i <= n; ++i) { scanf ("%d", a + i); } // if (k > n) { // while (1); // } que[1].val = a[1]; que[1].id = 1; int head = 1, tail = 1; for (int i = 2; i <= k; ++i) { //开始预处理 while (tail >= head && a[i] >= que[tail].val) --tail; ++tail; que[tail].val = a[i]; que[tail].id = i; } ans_max[++lenmax] = que[head].val; for (int i = k + 1; i <= n; ++i) { while (tail >= head && a[i] >= que[tail].val) --tail; ++tail; que[tail].val = a[i]; que[tail].id = i; while (head <= tail && que[head].id == i - k) ++head; ans_max[++lenmax] = que[head].val; } head = tail = 1; que[tail].val = a[1]; que[tail].id = 1; for (int i = 2; i <= k; ++i) { while (tail >= head && a[i] <= que[tail].val) --tail; ++tail; que[tail].val = a[i]; que[tail].id = i; } ans_min[++lenmin] = que[head].val; for (int i = k + 1; i <= n; ++i) { while (tail >= head && a[i] <= que[tail].val) --tail; ++tail; que[tail].val = a[i]; que[tail].id = i; while (head <= tail && que[head].id == i - k) ++head; ans_min[++lenmin] = que[head].val; //每次取队头就是ans } for (int i = 1; i <= lenmin; ++i) { printf ("%d ", ans_min[i]); } printf ("\n"); for (int i = 1; i <= lenmax; ++i) { printf ("%d ", ans_max[i]); } printf ("\n"); return ; } int main() { #ifdef local freopen("data.txt","r",stdin); #endif work (); return 0; }
既然选择了远方,就要风雨兼程~
posted on 2016-08-29 19:56 stupid_one 阅读(166) 评论(0) 编辑 收藏 举报