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;
    }
    
  • 相关阅读:
    VS2008正式版序列号
    清空SQL Server数据库中所有的用户表
    [原创]JavaScript调用Button的服务器端事件
    动态加载枚举 到 DropdownList
    [转载]静态构造函数
    SQL 事务 [两种]
    Jpg文件格式[参考]
    Delegate Event
    javascript 操作cookie类
    [共享]一个文件上传的控件,绝对是精品源码
  • 原文地址:https://www.cnblogs.com/kma093/p/10291461.html
Copyright © 2011-2022 走看看