zoukankan      html  css  js  c++  java
  • NEUOJ 1117: Ready to declare(单调队列)

    1117: Ready to declare

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 358  解决: 41
    [提交][状态][讨论版]

    题目描写叙述

    Finally, you find the most good-looking girl...
    You are going to write a letter to her. But you are not convident to be better than other boys. So you think you need a good chance...
    You have known that these days, she will meet N boys at all(N<=100000). The ith boy has a handsome value V[i](0<V[i]<10000). She will meet K(K<=N) boys at the same time, and when the first boy leave, the next boy join them. It is to say that she will meet first K boys in the list at first, then the first boy leave ,the k+1-th boy join. So she will meet boys N-K+1 times.
    You must want to join she and them when these boys are not handsome, so you need to calculate each meet's the least handsome value and the most.
    here is a sample when N=8,K=3
    boys                least     most
    [5 3 2] 1 1 10 2 3 25
    5 [3 2 1] 1 10 2 3 13
    5 3 [2 1 1] 10 2 3 12
    5 3 2 [1 1 10] 2 3 110
    5 3 2 1 [1 10 2] 3 110
    5 3 2 1 1 [10 2 3] 210

    输入

    There are several test cases, each case contains two lines.
    The first line is two number ,N K.
    The second line has N number, the handsome value.

    输出

    Each case output two lines.The first line is each meet's min handsome value, the second line is each meet's max handsome value.

    例子输入

    8 3
    5 3 2 1 1 10 2 3

    例子输出

    2 1 1 1 1 2
    5 3 2 10 10 10

    提示

    来源



    尽管正解是单调队列。但是我用的是两个栈实现的队列水过的。存下代码

    /*************************************************************************
        > File Name: Euler.cpp
        > Author: acvcla
        > QQ: 
        > Mail: acvcla@gmail.com 
        > Created Time: 2014年10月30日 星期四 11时19分11秒
     ************************************************************************/
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    const int maxn=1e5+5;
    int stack1[maxn],stack2[maxn],max2[maxn],max1,min2[maxn],min1;
    int top1,top2;
    void init(){
    	top1=top2=0;
    	max1=max2[top2]=0;
    	min1=min2[top2]=maxn;
    }
    int ans1[maxn],ans2[maxn];
    void deque(){
    
    	if(top2>0){
    		stack2[--top2];
    		return ;
    	}
    	while(top1>0){
    		stack2[top2]=stack1[--top1];
    		max2[top2]=max(top2>0?max2[top2-1]:0,stack2[top2]);
    		min2[top2]=min(top2>0?min2[top2-1]:maxn,stack2[top2]);
    		top2++;
    	}
    	max1=0;
    	min1=maxn;
    	--top2;
    } 
    int get_max_min(int x){
    	if(x)return max(max1,top2>0?max2[top2-1]:0);
    	return min(min1,top2>0?min2[top2-1]:maxn);
    }
    void push(int x){
    	max1=max(x,max1);
    	min1=min(x,min1);
    	stack1[top1++]=x;
    }
    int main()
    {
    	int n,k,x;
    	while(~scanf("%d%d",&n,&k)){
    		init();
    		int t=0,cnt=0;
    		for(int i=1;i<=n;i++){
    			scanf("%d",&x);
    			push(x);
    			++cnt;
    			if(cnt==k)
    			{
    				ans1[t]=get_max_min(0);
    				//cout<<"sldl"<<endl;
    				ans2[t++]=get_max_min(1);
    				deque();
    				cnt--;
    			}
    		}
    		for(int i=0;i<t;i++)printf("%d%c",ans1[i],i==t-1?'
    ':' ');
    		for(int i=0;i<t;i++)printf("%d%c",ans2[i],i==t-1?'
    ':' ');
    	}
    	return 0;
    }



    补上单调队列版

    #include <cstdio>
    #include <iostream>
    using namespace std;
    const int maxn =1e5 + 10;
    struct Queue
    {
    	int value;
    	int index;
    };
    Queue min_que[maxn],max_que[maxn];
    int n,k,num[maxn],front,rear;
    int delete_rear_inc(int f,int r,int d) 
    {
    	int mid;
    	while(f<=r){
    		mid=(f+r)/2;
    		if(min_que[mid].value==d) return mid;
    		if(min_que[mid].value>d) r=mid-1;
    		else f=mid+1;
    	}
    	return f;
    }
    int delete_rear_dec(int f,int r,int d) 
    {
    	int mid;
    	while(f<=r){
    		mid=(f+r)/2;
    		if(max_que[mid].value==d) return mid;
    		if(max_que[mid].value>d) f=mid+1;
    		else r=mid-1;
    	}
    	return f;
    }
    int main()
    {
    
    	while(~scanf("%d%d",&n,&k)){
    
    		for(int i=1;i<=n;i++)scanf("%d",&num[i]);
    
    		min_que[1].value=num[1];
    		front=rear=min_que[1].index=1;
    
    		for(int i=2;i<=k;i++) {
    			rear=delete_rear_inc(front,rear,num[i]);
    			min_que[rear].value=num[i];
    			min_que[rear].index=i;
    		}
    
    		printf("%d",min_que[1].value);
    		for(int i=k+1;i<=n;i++) {
    			rear=delete_rear_inc(front,rear,num[i]);
    			min_que[rear].value=num[i];
    			min_que[rear].index=i;
    			if(i-min_que[front].index>=k) front++;
    			printf(" %d",min_que[front].value);
    			if(i==n)puts("");
    		}
    
    		max_que[1].value=num[1];
    		front=rear=max_que[1].index=1;
    
    		for(int i=2;i<=k;i++) {
    			rear=delete_rear_dec(front,rear,num[i]);
    			max_que[rear].value=num[i];
    			max_que[rear].index=i;
    		}
    
    		printf("%d",max_que[1].value);
    		for(int i=k+1;i<=n;i++) {
    			rear=delete_rear_dec(front,rear,num[i]);
    			max_que[rear].value=num[i];
    			max_que[rear].index=i;
    			if(i-max_que[front].index>=k) front++;
    			printf(" %d",max_que[front].value);
    			if(i==n)puts("");
    		}
     	}
    	return 0;
    }


  • 相关阅读:
    hdu6229 Wandering Robots 2017沈阳区域赛M题 思维加map
    hdu6223 Infinite Fraction Path 2017沈阳区域赛G题 bfs加剪枝(好题)
    hdu6438 Buy and Resell 买卖物品 ccpc网络赛 贪心
    hdu6441 Find Integer 求勾股数 费马大定理
    bzoj 1176 Mokia
    luogu 3415 祭坛
    bzoj 1010 玩具装箱
    bzoj 3312 No Change
    luogu 3383【模板】线性筛素数
    bzoj 1067 降雨量
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5357737.html
Copyright © 2011-2022 走看看