zoukankan      html  css  js  c++  java
  • POJ2823 (单调队列)

    POJ2823

    题意:给n个数字,有一个大小为k的框,从左往右框数字,一共框n-k+1次,问每次框中数字的最大,最小值。

    思路:可以先思考只求最大值,因为1e6的数字,维护最大堆的复杂度是nlogn,肯定超时了。我们可以想到,框每次向右移动一格,只会增加一个数字,减少一个数字,可以想到,我们要维护一个序列,

    通过这个序列来更新最大值,抹除左边出去的值,这个可以想到要用单调队列来解决,我们维护一个单调递减的序列,每次新加的数字如果最小,放队尾,如果较大,就依次删队尾元素,找到它该在的位置。通过这个方式,我们使一个队列,始终有着目前的最大值。

    总之,对于求最大值,维护一个递减序列,求最小值,维护一个递增序列。

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=1e6+10;
    struct note
    {
        int x,y;
    } q[maxn];
    
    int minn[maxn],maxx[maxn];
    int a[maxn];
    int n,k;
    void getmax()
    {
        int head=1;
        int tail=0;
        for(int i=1; i<=k-1; i++)
        {
            while(q[tail].x<=a[i]&&head<=tail)
            {
                tail--;
            }
            q[++tail].x=a[i];
            q[tail].y=i;
        }
        for(int i=k; i<=n; i++)
        {
            while(q[tail].x<=a[i]&&head<=tail)
            {
                tail--;
            }
            q[++tail].x=a[i];
            q[tail].y=i;
            while(q[head].y<(i-k+1))
            {
                head++;
            }
            maxx[i-k+1]=q[head].x;
        }
    }
    
    void getmin()
    {
        int head=1;
        int tail=0;
        for(int i=1;i<=k-1;i++)
        {
            while(a[i]<=q[tail].x&&head<=tail)
            {
                tail--;
            }
            q[++tail].x=a[i];q[tail].y=i;
        }
        for(int i=k;i<=n;i++)
        {
            while(a[i]<=q[tail].x&&head<=tail)
            {
                tail--;
            }
            q[++tail].x=a[i];q[tail].y=i;
            while(q[head].y<(i-k+1))
            {
                head++;
            }
            minn[i-k+1]=q[head].x;
        }
    }
    int main()
    {
    
        scanf("%d%d",&n,&k);
        for(int i=1; i<=n; i++)
            scanf("%d",&a[i]);
        getmax();
        getmin();
        for(int i=1; i<=n-k+1; i++)
            printf("%d ",minn[i]);
        printf("
    ");
        for(int i=1;i<=n-k+1;i++)
            printf("%d ",maxx[i]);
    }
  • 相关阅读:
    搭建Keil C51开发环境
    源码分析之Handler
    Android中的算法
    Android中的数据结构
    高级UI-UI绘制流程
    高级UI-Path和PathMeasure
    高级UI-画板Canvas
    高级UI-滤镜和颜色通道
    高级UI-高级渲染
    高级UI-画笔Paint
  • 原文地址:https://www.cnblogs.com/dongdong25800/p/11112630.html
Copyright © 2011-2022 走看看