• [单调队列] poj 2823 Sliding Window


    题意:

    给你n个数和一个k

    把n分成连续的n-k+1个区间

    第一行按顺序输出每一个区间的最小值,第二行是最大值。

    思路:

    单调队列的模板题,这里注意的是插入队尾的时候须要二分加速

    代码:

    #include"stdio.h"
    #include"algorithm"
    #include"string.h"
    #include"iostream"
    #include"queue"
    #include"map"
    #include"vector"
    #include"string"
    #include"cmath"
    using namespace std;
    #define N 2222222
    struct node
    {
        int x,s;
    };
    int cmp(node a,node b)
    {
        return a.s<b.s;
    }
    int cmp1(node a,node b)
    {
        return a.s>b.s;
    }
    node q[N],v[N];
    int finde_max(int l,int r,int k)
    {
        int ans=-1;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(q[mid].s>k)
            {
                ans=mid;
                l=mid+1;
            }
            else r=mid-1;
        }
        return ans;
    }
    int finde_min(int l,int r,int k)
    {
        int ans=-1;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(q[mid].s<k)
            {
                ans=mid;
                l=mid+1;
            }
            else r=mid-1;
        }
        return ans;
    }
    int main()
    {
        int n,k;
        while(scanf("%d%d",&n,&k)!=-1)
        {
            for(int i=1; i<=n; i++)
            {
                scanf("%d",&v[i].s);
                v[i].x=i;
            }
            int head=0,ed=0;
            for(int i=1;i<=k;i++)  q[ed++]=v[i];
            sort(q,q+k,cmp);
            for(int i=k; i<=n; i++)
            {
                if(head>ed) q[++ed]=v[i];         //入队
                else
                {
                    int tep=finde_min(head,ed,v[i].s);
                    if(tep==-1) q[ed=head]=v[i];
                    else q[ed=tep+1]=v[i];
                }
                while(q[head].x+k<=i) head++;     //出队
                printf(i==n?"%d
    ":"%d ",q[head].s);
            }
    
            head=0,ed=0;
            for(int i=1;i<=k;i++)  q[ed++]=v[i];
            sort(q,q+k,cmp1);
            for(int i=k; i<=n; i++)
            {
                if(head>ed) q[++ed]=v[i];         //入队
                else
                {
                    int tep=finde_max(head,ed,v[i].s);
                    if(tep==-1) q[ed=head]=v[i];
                    else q[ed=tep+1]=v[i];
                }
                while(q[head].x+k<=i) head++;     //出队
                printf(i==n?

    "%d ":"%d ",q[head].s); } } return 0; }



  • 相关阅读:
    SQL的Demo 由Access改为SQLite
    Delphi10.3ComboBoxEx下拉左边带图标
    uniGUI学习之IconCombobox(53)
    MySQL的图形GUI界面Navicat操作(03)
    delphi10.3安装使用mySQL(02)从SQLite 转移至Mysql
    [转] Java虚拟机原理图解 系列
    [转]ASM插入代码 visitFieldInsn
    [转]大话+图说:Java字节码指令——只为让你懂
    [转]smali语言之locals和registers的区别
    [转]Smali浅析及dex,java互转
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/7225530.html
Copyright © 2020-2023  润新知