首页 > 代码库 > poj - 2823 - Sliding Window(单调队列)

poj - 2823 - Sliding Window(单调队列)

题意:n个数的序列,长为k个数的窗口,窗口从左从右移,问窗口移动过程中每个状态的最小最大值。

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

——>>单调队列练手。。

C++用时5391MS,G++会TLE。。不解。。望路过的朋友指导一下原因。。

#include <cstdio>
#include <vector>
#include <queue>

const int MAXN = 1000000 + 1;

int arrIn[MAXN];
int arrRet[MAXN];
int arrDq[MAXN];
int arrId[MAXN];

void Pop(const int& nVal, const bool& bFlag, const int& nFront, int& nTail)
{
    if (!bFlag)
    {
        while (nFront != nTail && nVal <= arrDq[nTail - 1])
        {
            nTail--;
        }
    }
    else
    {
        while (nFront != nTail && nVal >= arrDq[nTail - 1])
        {
            nTail--;
        }
    }
}

void GetRet(int n, int k, bool bFlag = false)
{
    int nFront = 0;
    int nTail = 0;

    for (int i = 0; i < n; ++i)
    {
        Pop(arrIn[i], bFlag, nFront, nTail);
        arrDq[nTail++] = arrIn[i];
        arrId[nTail - 1] = i;
        while (nFront != nTail && arrId[nFront] <= i - k)
        {
            nFront++;
        }
        if (i >= k - 1)
        {
            arrRet[i - k + 1] = arrDq[nFront];
        }
    }
}

void Read(int n)
{
    getchar();
    for (int i = 0; i < n; ++i)
    {
        scanf("%d", arrIn + i);
    }
}

void Output(int* arr, int n)
{
    for (int i = 0; i < n - 1; ++i)
    {
        printf("%d ", arr[i]);
    }
    if (n)
    {
        printf("%d\n", arr[n - 1]);
    }
}

int main()
{
    int n, k;

    while (scanf("%d%d", &n, &k) == 2)
    {
        Read(n);
        GetRet(n, k);
        Output(arrRet, n - k + 1);
        GetRet(n, k, true);
        Output(arrRet, n - k + 1);
    }

    return 0;
}

poj - 2823 - Sliding Window(单调队列)