poj 2823 Sliding Window

/* Name:poj 2823 Sliding Window Author: Unimen Date: 08/05/11 18:24 Description: 单调队列 */ /* 解题报告: 单调队列的精典应用 */ //STL队列实现 #include <cstdio> #include <deque> using namespace std; const int MAXN = 1000001; struct Node //单调队列里存放人数据类型 { int value; int index; }; Node input[MAXN]; //输入数据 deque<Node> dque1; //单调递增队列 deque<Node> dque2; //单调递减队列 int len, k; void addmin(Node &node) { while(!dque1.empty() && dque1.back().value>node.value) dque1.pop_back(); dque1.push_back(node); } void addmax(Node &node) { while(!dque2.empty() && dque2.back().value<node.value) dque2.pop_back(); dque2.push_back(node); } int getmin(int index) { while(dque1.front().index < index) dque1.pop_front(); return dque1.front().value; } int getmax(int index) { while(dque2.front().index < index) dque2.pop_front(); return dque2.front().value; } inline void readint(int &ans) { int sgn; char c; c = getchar(); while(c!='-' && c<'0' || c>'9') c = getchar(); sgn = (c=='-' ? -1 : 1); ans = (c=='-' ? 0 : c-'0'); while((c=getchar())>='0' && c<='9') ans = ans * 10 + c - '0'; ans *= sgn; } inline void putint(int x) { int store[20]; int nBase = 0; if(0 == x) putchar('0'); if(x<0) { putchar('-'); x = -x; } for(; x; x/=10) { store[nBase++] = x%10; } while(nBase--) { putchar(store[nBase]+'0'); } } int main() { int i; scanf("%d%d", &len, &k); for(i=1; i<=len; ++i) { readint(input[i].value); input[i].index = i; if(i < k) { addmin(input[i]); addmax(input[i]); } } //输出最小值 for(i=k; i<=len; ++i) { addmin(input[i]); putint(getmin(i-k+1)); putchar(' '); } printf("/n"); //输出最大值 for(i=k; i<=len; i++) { addmax(input[i]); putint(getmax(i-k+1)); putchar(' '); } printf("/n"); return 0; } //手写队列实现 #include <iostream> #include <cstdio> using namespace std; int que1[1000001][2], que2[1000001][2], input[1000001], start1, tail1, start2, tail2; int len, k; inline void addmin(int value, int index) { while(start1<=tail1 && que1[tail1][0]>value) tail1--; tail1++; que1[tail1][0] = value; que1[tail1][1] = index; } inline void addmax(int value, int index) { while(start2<=tail2 && que2[tail2][0]<value) tail2--; tail2++; que2[tail2][0] = value; que2[tail2][1] = index; } inline int getmin(int index) { while(que1[start1][1] < index) start1++; return que1[start1][0]; } inline int getmax(int index) { while(que2[start2][1] < index) start2++; return que2[start2][0]; } inline void readint(int &ans) { int sgn; char c; c = getchar(); while(c!='-' && c<'0' || c>'9') c = getchar(); sgn = (c=='-' ? -1 : 1); ans = (c=='-' ? 0 : c-'0'); while((c=getchar())>='0' && c<='9') ans = ans * 10 + c - '0'; ans *= sgn; } inline void putint(int x) { int store[20]; int nBase = 0; if(0 == x) putchar('0'); if(x<0) { putchar('-'); x = -x; } for(; x; x/=10) { store[nBase++] = x%10; } while(nBase--) { putchar(store[nBase]+'0'); } } int main() { while(scanf("%d%d", &len, &k) != EOF) { start1 = start2 = 0; tail1 = tail2 = -1; for(int i=1; i<=len; ++i) { readint(input[i]); if(i<k) { addmin(input[i], i); addmax(input[i], i); } } //输出最小值 for(int i=k; i<len; ++i) { addmin(input[i], i); putint(getmin(i-k+1)); putchar(' '); } addmin(input[len], len); putint(getmin(len-k+1)); printf("/n"); //输出最大值 for(int i=k; i<len; ++i) { addmax(input[i], i); putint(getmax(i-k+1)); putchar(' '); } addmax(input[len], len); putint(getmax(len-k+1)); printf("/n"); } return 0; }

你可能感兴趣的:(poj 2823 Sliding Window)