zoukankan      html  css  js  c++  java
  • Poj 2823 Sliding Window(单调队列)

    题目描述:http://poj.org/problem?id=2823

    思路分析:求某个区间的最大与最小值,可以使用两个单调队列,由于需要在队列前删除元素和在队列后增加元素,所以考虑使用双端队列;

    在双端队列中记录元素的下标,另外,双端队列为单调队列,满足单调非递增或单调非递减,则队列第一个元素为区间最大或最小元素;

    这样可以找出区间中的最大与最小值。该算法为线性时间,时间复杂度为O(N)。

    代码如下:

    #include <iostream>
    #include <deque>
    
    #define MAX_N ( 100000 + 10 )
    
    using namespace std;
    int A[MAX_N];
    deque<int> D( MAX_N );
    
    
    void MaxOfSliding( int n, int k );
    void MinOfSliding( int n, int k );
    
    int main( )
    {
        int n, k;
    
        while ( scanf( "%d %d", &n, &k ) != EOF )
        {
            for ( int i = 0; i < n; ++i )
                scanf( "%d", &A[i] );
    
            MinOfSliding( n, k );
            MaxOfSliding( n, k );
        }
    
        return 0;
    }
    
    void MaxOfSliding( int n, int k )
    {
        int i;
    
        for ( i = 0; i < k - 1; ++i )
        {
            if ( !D.empty( ) && A[i] > D.back( ) )
                D.pop_back( );
            D.push_back( i );
        }
    
        for ( i = k - 1; i < n; ++i )
        {
            while ( !D.empty( ) && i - D.front( ) >= k )
                D.pop_front( );
    
            while ( !D.empty( ) && A[i] > D.back( ) )
                D.pop_back( );
            D.push_back( i );
    
            printf( "%d ",A[D.front( )] );
        }
        D.clear( );
        printf( "
    " );
    }
    
    void MinOfSliding( int n, int k )
    {
        int i;
    
        for ( i = 0; i < k - 1; ++i )
        {
            if ( !D.empty( ) && A[i] < D.back( ) )
                D.pop_back( );
            D.push_back( i );
        }
    
        for ( i = k - 1; i < n; ++i )
        {
            while ( !D.empty( ) && i - D.front( ) >= k )
                D.pop_front( );
    
            while ( !D.empty( ) && A[i] < D.back( ) )
                D.pop_back( );
            D.push_back( i );
    
            printf( "%d ", A[D.front( )] );
        }
        D.clear( );
        printf( "
    " );
    }
  • 相关阅读:
    真正的e时代
    在线手册
    UVA 10616 Divisible Group Sums
    UVA 10721 Bar Codes
    UVA 10205 Stack 'em Up
    UVA 10247 Complete Tree Labeling
    UVA 10081 Tight Words
    UVA 11125 Arrange Some Marbles
    UVA 10128 Queue
    UVA 10912 Simple Minded Hashing
  • 原文地址:https://www.cnblogs.com/tallisHe/p/4007877.html
Copyright © 2011-2022 走看看