POJ 2823 Sliding Window(单调队列)

题目链接:http://poj.org/problem?id=2823

题意:n个数字。有一个长度为m的区间依次从左向右移动,每次移动一个数字。输出每次区间中的最大值和最小值。

思路:维护队列中升序或者降序且队头的位置与当前位置差不大于m。

 #include <iostream>

 #include <cstdio>

 #include <cstring>

 using namespace std;

 

 const int MAX=1000005;

 int a[MAX],n,m;

 int Q[MAX],head,tail;

 

 void deal1()

 {

     head=tail=0;

     int i;

     for(i=1;i<=n;i++)

     {

         while(head<tail&&a[i]<=a[Q[tail-1]]) tail--;

         Q[tail++]=i;

         if(i>=m)

         {

             while(head<tail&&Q[head]<=i-m) head++;

             printf("%d ",a[Q[head]]);

         }

     }

     puts("");

 }

 

 void deal2()

 {

     head=tail=0;

     int i;

     for(i=1;i<=n;i++)

     {

         while(head<tail&&a[i]>=a[Q[tail-1]]) tail--;

         Q[tail++]=i;

         if(i>=m)

         {

             while(head<tail&&Q[head]<=i-m) head++;

             printf("%d ",a[Q[head]]);

         }

     }

     puts("");

 }

 

 int main()

 {

     while(scanf("%d%d",&n,&m)!=-1)

     {

         int i;

         for(i=1;i<=n;i++) scanf("%d",&a[i]);

         deal1();

         deal2();

     }

     return 0;

 }

  

 

 

你可能感兴趣的:(window)