1 /***************************************************************** 2 题目: Sliding Window(poj 2823) 3 链接: http://poj.org/problem?id=2823 4 题意: 给一个数列,找所有连续k个数的最小值和最大值。 5 算法: 单调队列(入门) 6 *******************************************************************/ 7 #include<iostream> 8 #include<cstdio> 9 #include<cstring> 10 #include<algorithm> 11 using namespace std; 12 13 const int mx=1000006; 14 struct Q 15 { 16 int x; 17 int id; 18 }; 19 Q q[mx]; 20 int a[mx]; 21 22 int main() 23 { 24 int n,k; 25 while (~scanf("%d%d",&n,&k)) 26 { 27 for (int i=1;i<=n;i++) scanf("%d",&a[i]); 28 int h=1,r=0,i; 29 ///初始化队列,这步一定要加 30 for (int i=0;i<1000006;i++) q[i].id=1000006; 31 32 ///先把前k个元素放入队列 33 for (i=1;i<=k;i++) 34 { 35 while (r>=h&&q[r].x>a[i]) r--; ///保证队列中元素递增,虽然有些元素会覆盖,但覆盖的元素 36 ///是不会输出的元素。 37 q[++r].x=a[i]; 38 q[r].id=i; 39 } 40 41 for (;i<=n;i++) 42 { 43 printf("%d ",q[h].x); ///由于队列只有k个元素,所以第一一定是最小的 44 while (q[h].id<=i-k) h++; ///删除一些元素,保证下标在i-k+1到i的元素在队列中 45 while (r>=h&&q[r].x>a[i]) r--; 46 q[++r].x=a[i]; 47 q[r].id=i; 48 49 } 50 printf("%d\n",q[h].x); 51 ///最大值求法和最小值一样 52 for (int i=0;i<1000006;i++) q[i].id=1000006; 53 h=1,r=0; 54 for (i=1;i<=k;i++) 55 { 56 while (r>=h&&q[r].x<a[i]) r--; 57 q[++r].x=a[i]; 58 q[r].id=i; 59 } 60 for (;i<=n;i++) 61 { 62 printf("%d ",q[h].x); 63 while (q[h].id<=i-k) h++; 64 while (r>=h&&q[r].x<a[i]) r--; 65 q[++r].x=a[i]; 66 q[r].id=i; 67 } 68 printf("%d\n",q[h].x); 69 } 70 }