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 }

 

posted on 2016-08-05 19:31  pb2016  阅读(212)  评论(0编辑  收藏  举报