洛谷-P1886-滑动窗口-优先队列

题意:中文题目,链接

优先队列,输出最小值,建立递增队列,这样队头一定是最小值。每次pop_back的时候,都要检查,当前应该输入是第几个窗口,防止把应该输出的值给pop出去。

注意,第curK个窗口的范围应该是,curK到curK+K

#include"pch.h"
#include <string>
#include<iostream>
#include<map>
#include<memory.h>
#include<vector>
#include<algorithm>
#include<queue>
#include<vector>
#include<stack>
#include<math.h>
#include<iomanip>
#include<bitset>
#include"math.h"
namespace cc
{
    using std::cout;
    using std::endl;
    using std::cin;
    using std::map;
    using std::vector;
    using std::string;
    using std::sort;
    using std::priority_queue;
    using std::vector;
    using std::swap;
    using std::stack;
    using std::queue;
    using std::bitset;
    using std::deque;


    const int N = 1000010;
    //constexpr int N = 20;

    class Node
    {
    public:
        int num;
        int index;
        Node() {};
        Node(int num, int index) :num(num), index(index)
        {
        }
    };

    deque<Node> q;
    int a[N];
    int n, k;
    int curK = 0;
    int first = 1;
    void print(Node& nn)
    {
        if (first)
        {
            first = 0;
            cout << q.front().num;
        }
        else
            cout << " " << q.front().num;
        curK++;
    }

    bool in(int index)
    {
        if (curK + k > index  && curK <= index)
        {
            return true;
        }
        return false;
    }

    void printMin() 
    {
        while (q.empty() == false)
            q.pop_front();
        first = 1;
        curK = 0;
        //构建递增队列
        for (int i = 0;i < n;i++)
        {
            while (q.empty() == false
                && q.back().num >= a[i]
                && (i - q.back().index) <= (k - 1))
            {
                //check is in curK
                Node nn = q.back();
                //error
                if ((in(nn.index) && in(i) == false) || nn.index > (curK+k))
                {
                    //in and i is not in,should cout
                    Node nnn = q.front();
                    if (in(nnn.index))
                        print(nn);
                    else
                        q.pop_front();
                    continue;
                }
                q.pop_back();
            }
            q.push_back(Node(a[i], i));
        }
        //
        while (q.empty() == false)
        {
            Node nn = q.front();
            if (in(nn.index) && curK != (n - k + 1))
            {
                print(nn);
            }
            else
            {
                q.pop_front();
            }
        }
    }



    void printMax()
    {
        while (q.empty() == false)
            q.pop_front();
        first = 1;
        curK = 0;
        //构建递减队列,队头元素最大
        for (int i = 0;i < n;i++)
        {
            while (q.empty() == false
                && q.back().num <= a[i]
                && (i - q.back().index) <= (k - 1))
            {
                //check is in curK
                Node nn = q.back();
                if ((in(nn.index) && in(i) == false) || nn.index > (curK + k))
                {
                    //in and i is not in,should cout
                    Node nnn = q.front();
                    if (in(nnn.index))
                        print(nn);
                    else
                        q.pop_front();
                    continue;
                }
                q.pop_back();
            }
            q.push_back(Node(a[i], i));
        }
        //
        while (q.empty() == false)
        {
            Node nn = q.front();
            if (in(nn.index) && curK != (n - k + 1))
            {
                print(nn);
            }
            else
            {
                q.pop_front();
            }
        }
    }


    void solve()
    {
        while (cin >> n >> k)
        {
            //cal totalK.
            for (int i = 0;i < n;i++)
                cin >> a[i];
            printMin();
            cout << endl;
            printMax();
            cout << endl;


        }



    }
};


void subset(int n, int * a)
{
    for (int i = 0;i < (1 << n);i++)
    {
        for (int j = 0;j < i; j++)
        {
            if (i&(1 << j))
            {
                std::cout << a[j] << " ";
            }
        }
        std::cout << std::endl;
    }

}



int main()
{

#ifndef ONLINE_JUDGE
    freopen("d://1.text", "r", stdin);
    //freopen("d://1.out", "w", stdout);
    //freopen("d://1.out", "w", stdout);
#endif // !ONLINE_JUDGE
    cc::solve();
    return 0;
}
原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/11185998.html