zoukankan      html  css  js  c++  java
  • 洛谷p1886 滑动窗口

    题目链接:###

    滑动窗口

    题目分析:###

    单调队列经典题,话说我第一次做这个题的时候是用线段树水的
    两个单调队列分别维护最小最大值,因为窗口有k的长度限制所以维护下标更方便
    又由于是从左往右扫过去的,所以可以保证下标和值都是单调的
    读一个维护一个,以单增队列为例,每读入一个元素就把前面比它大的都弹出,然后将元素入队
    因为窗口有k长,所以i>=k的时候再开始记录答案,将已经在窗口外的元素(即i-元素下标>=k)从队头弹出队列(这时候就体现出维护下标的作用了,维护元素的话就要再开一个数组记下标),做完之后队头元素就是最小值,记录在ans1中
    单减队列同理
    最后输出两个数组就好了


    代码:###

    #include<bits/stdc++.h>
    #define MAXN (1000000+5)
    using namespace std;
    inline int read(){
        int f=1,cnt=0;char c;
        c=getchar();
        while(!isdigit(c)){if(c=='-')f=-f;c=getchar();}
        while(isdigit(c)){cnt=cnt*10+c-'0';c=getchar();}
        return cnt*f;
    }
    int q1[MAXN],q2[MAXN];//q1->max,q2->min
    int n,k,a[MAXN];
    int l1,l2,r1,r2; 
    int ans_min[MAXN],ans_max[MAXN];
    int main(){
    	n=read();k=read();
    	for(register int i=1;i<=n;i++){
    		a[i]=read();
    		while(l1<=r1&&a[i]>=a[q1[r1]])r1--;
    		q1[++r1]=i;
    		while(l2<=r2&&a[i]<=a[q2[r2]])r2--;
    		q2[++r2]=i;
    		if(i>=k){
    			while(l1<=r1&&i-q1[l1]>=k)l1++;
    			while(l2<=r2&&i-q2[l2]>=k)l2++;
    			ans_max[i-k+1]=a[q1[l1]];ans_min[i-k+1]=a[q2[l2]];
    		}
    	}
    	for(register int i=1;i<=n-k+1;i++)printf("%d ",ans_min[i]);
    	printf("
    ");
    	for(register int i=1;i<=n-k+1;i++)printf("%d ",ans_max[i]);
    	return 0;
    }
    
  • 相关阅读:
    CISCO DHCP全攻略详解
    CentOS配置远程日志服务器
    CentOS下的日志切割
    CentOS日志的简单介绍
    H3C Telnet 配置
    CentOS7图形界面与命令行界面切换
    思科4506E做ehterchannel故障排查
    EtherChannel Cisco 端口聚合详解
    算法练习2之单链表求和
    Retrofit2的GsonConverterFactory.create()和RxJava2CallAdapterFactory.create()的实现过程以及执行过程
  • 原文地址:https://www.cnblogs.com/kma093/p/10291461.html
Copyright © 2011-2022 走看看