• poj2823 Sliding Window


    单调队列
    (题面:http://poj.org/problem?id=2823)
    题意就是给一堆数和一个窗口,求窗口滑到某一位置时里面的最小值最大值
    于是乎我们有了单调队列做法
    这题用STL的双端队列貌似会RE,自己写一个就好了
    我们以最小值为例:
    8 3
    1 3 -1 -3 5 6 7 8(注意和题面中数据不太一样)
    维护两个deque,其中一个存值(我们用英文字母q表示),另一个存下标(我们用英文字母p表示)
    (1)1号元素"1"入队,q={1},p={1}
    (2)2号元素"3"入队,此时"3"发现他前面有个"1",但是他毫无顾忌,因为如果窗口左边界过了1而后边的数都比他大的话,他有可能是最小值的,所以把"3"入队,q={1,3},p={1,2}
    (3)3号元素"-1"入队,此时"-1"发现他前面有个"3",而"-1"是在"3"的后面被加入的,所以只要"3"没有出窗口,"-1"肯定不会出窗口,"-1"<"3",所以我们要把"3"舍弃,"3"从末尾出队,此时"-1"又发现前面有个"1",同理"1"也从末尾出队,"-1"入队,此时q={-1},p={3},发现已经找过了3个元素,从今以后可以输出了,此时输出"-1"为[1,3]的最小值
    (4)4号元素"-3"入队,同上我们要把"-1"从末尾出队,"-3"入队,所以q={-3},p={4},输出"-3"为[2,4]的最小值
    (5)5号元素"5"入队,根据(2)中的解释,他也可能成为最小值的,将5从末尾入队q={-3,5},p={4,5}输出"-3"为[3,5]的最小值
    (6)6号元素"6"入队,此时q={-3,5,6},p={4,5,6},输出"-3"为[4,6]的最小值
    (7)7号元素"7"入队,此时q={-3,5,6,7},p={4,5,6,7},输出"-3"为[5,7]的最小值,哎不对,"-3"不是4号元素吗,现在已经过时了,这时候我们应该判断一下队首元素序号+k是否大于i,不是的话弹出,所以这时候我们要把"-3"从队首弹出队列,此时q={5,6,7},p={5,6,7},输出"5"为[5,7]的最小值
    (8)8号元素"8"入队,此时队首的5号元素也该出队了,q={6,7,8},p={6,7,8},输出"6"作为[6,8]的最小值
    所以答案为-1 -3 -3 -3 5 6
    然后一定要把队列清空了,再跑最大值,最大值就是比较的时候把小于号改成大于号即可
    码子:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    
    struct deque
    {int aa[1000010];
    	int head,tail;
    	deque(){head=1;tail=1;}//[head,tail)
    	bool empty(){return head==tail;}
    	void push_back(int x){aa[tail++]=x;}
    	void pop_back(){tail--;}
    	void pop_front(){head++;}
    	int back(){return aa[tail-1];}
    	int front(){return aa[head];}
    	void clear(){memset(aa,0,sizeof(aa));head=tail=1;}
    }p,q;
    int n,k,a[1000010];
    int main()
    {
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=n;i++)
    		scanf("%d",&a[i]);
    	for(int i=1;i<=n;i++)
    	{
    		while(!q.empty()&&q.back()>a[i])
    		{
    			q.pop_back();
    			p.pop_back();
    		}
    		if(!p.empty()&&p.front()+k<=i)
    		{
    			q.pop_front();
    			p.pop_front();
    		}
    		q.push_back(a[i]);
    		p.push_back(i);
    		if(i>=k)printf("%d%c",q.front(),i==n?'
    ':' ');
    	}
    	q.clear();
    	p.clear();
    	for(int i=1;i<=n;i++)
    	{
    		while(!q.empty()&&q.back()<a[i])
    		{
    			q.pop_back();
    			p.pop_back();
    		}
    		if(!p.empty()&&p.front()+k<=i)
    		{
    			q.pop_front();
    			p.pop_front();
    		}
    		q.push_back(a[i]);
    		p.push_back(i);
    		if(i>=k)printf("%d%c",q.front(),i==n?'
    ':' ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    没有比脚更长的路 没有比人更高的山
    Nginx---应用场景小结
    程序员北漂6年,活着 ---纪念逝去的青春
    程序员/PM怎么让项目预估的时间更加准确
    程序员从技术开发到项目管理PM--思维转变
    什么是MSF
    程序员有七个等级?你又属于哪个等级呢?
    linux之 sed 基础
    linux之awk基础
    centos 7 jenkins 部署
  • 原文地址:https://www.cnblogs.com/oier/p/8716031.html
Copyright © 2020-2023  润新知