zoukankan      html  css  js  c++  java
  • POJ 2823 Sliding Window

    题意:滑窗问题。一个长度为n的序列,分别求前k个数中的最值,第2个到第k + 1个数中的最值,...,直到最后一个元素。

    解法:单调队列。对于求最小值来说,题中的样例k为3,序列为为

                     1 3 -1 -3 5 3 6 7

    每次放入数字前,检查队头的编号,看是否已经超过了滑窗的范围,如果超过了弹出队头;还要看队尾元素是否比将要放入的数字大,因为新放入的数字如果比较小那么之前放入的大的数字肯定不可能是答案了,所以要弹出。这两个操作完成后再放入新插入的元素。此时队头元素即为当前滑窗的答案。

    样例解释为:

    队列              答案

    1                      -

    1  3                  -

    -1                    -1

    -3                    -3

    -3 5                 -3

    -3 3                 -3

    3 6                   3

    3 6 7                3

    代码:

    用了双端队列……勉强水过……用数组模拟更快……然而我比较懒……嗯哼

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<string.h>
    #include<math.h>
    #include<limits.h>
    #include<time.h>
    #include<stdlib.h>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #include<deque>
    #define LL long long
    using namespace std;
    const int MAXN = 1000005;
    struct node
    {
        int v, pos;
        node(int v, int pos) : v(v), pos(pos) {}
        node() {}
    }num[MAXN];
    int ans1[MAXN], ans2[MAXN];
    deque <node> maxn, minn;
    int main()
    {
        int n, k;
        while(~scanf("%d%d", &n, &k))
        {
            for(int i = 0; i < n; i++)
            {
                scanf("%d", &num[i].v);
                num[i].pos = i;
            }
            int ans = 0;
            for(int i = 0; i < n; i++)
            {
                if(!minn.empty() && minn.front().pos <= i - k)
                    minn.pop_front();
                while(!minn.empty() && minn.back().v >= num[i].v)
                    minn.pop_back();
                minn.push_back(num[i]);
                if(i >= k - 1)
                {
                    ans = minn.front().v;
                    ans1[i - k + 1] = ans;
                }
                while(!maxn.empty() && maxn.back().v <= num[i].v)
                    maxn.pop_back();
                if(!maxn.empty() && maxn.front().pos <= i - k)
                    maxn.pop_front();
                maxn.push_back(num[i]);
                if(i >= k - 1)
                {
                    ans = maxn.front().v;
                    ans2[i - k + 1] = ans;
                }
            }
            for(int i = 0; i < n - k + 1; i++)
            {
                if(i)
                    printf(" ");
                printf("%d", ans1[i]);
            }
            puts("");
            while(!minn.empty())
                minn.pop_back();
            for(int i = 0; i < n - k + 1; i++)
            {
                if(i)
                    printf(" ");
                printf("%d", ans2[i]);
            }
            puts("");
            while(!maxn.empty())
                maxn.pop_back();
        }
        return 0;
    }
    

      

  • 相关阅读:
    数据文件对应的磁盘坏掉了,没有归档,没有备份
    Oracle OEM重建
    Verilog编码指南
    UART串口协议
    信号完整性以及串扰
    Perl-由报表转命令(展讯2015)
    论文-ShuffleNet V2: Practical Guidelines for Efficient CNN Architecture Design
    时序路径分析模式
    后端设计各种设计文件格式说明
    Verilog-小数分频器(1.5)实现(待写)
  • 原文地址:https://www.cnblogs.com/Apro/p/4568801.html
Copyright © 2011-2022 走看看