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 2
5

5 [3 2 1] 1 10 2 3 1
3

5 3 [2 1 1] 10 2 3 1
2

5 3 2 [1 1 10] 2 3 1
10

5 3 2 1 [1 10 2] 3 1
10

5 3 2 1 1 [10 2 3] 2
10

输入

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

提示

来源

2011.12

虽然正解是单调队列,可是我用的是两个栈实现的队列水过的,存下代码,这种比单调队列支持的更多

/*************************************************************************
    > File Name: Euler.cpp
    > Author: acvcla
    > QQ:
    > Mail: [email protected]
    > 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?'\n':' ');
		for(int i=0;i<t;i++)printf("%d%c",ans2[i],i==t-1?'\n':' ');
	}
	return 0;
}
时间: 2024-12-23 14:26:09

NEUOJ 1117: Ready to declare(单调队列)的相关文章

neuoj 1117 Ready to declare

用线段树做的,,,,很笨,,,,,,最大最小分开来写的,,,,,,代码很长不过一半是复制下来的了..... 题意就是求每个小区间的最大最小值~ #include<stdio.h> #include<string.h> #include <algorithm> #include <bits/stdc++.h> using namespace std; #define maxn 222222 #define lson l,m,rt<<1 #defin

洛谷 U4792 Acheing 单调队列

/*洛谷 U4792 Acheing 二维线段树 n*n*logn*logn T成傻逼2333 */ #include<iostream> #include<cstdio> #include<cstring> #define maxn 1010 #define lc k*2 #define rc k*2+1 #define mid (l+r)/2 using namespace std; int n,m,k,g[maxn][maxn],x,y,z; int x1,x2,

【动态规划】【单调队列】tyvj1305 最大子序和

http://blog.csdn.net/oiljt12138/article/details/51174560 单调队列优化dp #include<cstdio> #include<deque> #include<algorithm> #include<iostream> using namespace std; typedef long long ll; int n,m; ll a[300100],ans; deque<int>q; int

hdu_5884_Sort(二分+单调队列)

题目链接:hdu_5884_Sort 题意: 有n个数,每个数有个值,现在你可以选择每次K个数合并,合并的消耗为这K个数的权值和,问在合并为只有1个数的时候,总消耗不超过T的情况下,最小的K是多少 题解: 首先要选满足条件的最小K,肯定会想到二分. 然后是如何来写这个check函数的问题 我们要贪心做到使消耗最小,首先我们将所有的数排序 然后对于每次的check的mid都取最小的mid个数来合并,然后把新产生的数扔进优先队列,直到最后只剩一个数. 不过这样的做法是n*(logn)2 ,常数写的小

[Vijos 1243]生产产品(单调队列优化Dp)

Description 在经过一段时间的经营后,dd_engi的OI商店不满足于从别的供货商那里购买产品放上货架,而要开始自己生产产品了!产品的生产需要M个步骤,每一个步骤都可以在N台机器中的任何一台完成,但生产的步骤必须严格按顺序执行.由于这N台机器的性能不同,它们完成每一个步骤的所需时间也不同.机器i完成第j个步骤的时间为T[i,j].把半成品从一台机器上搬到另一台机器上也需要一定的时间K.同时,为了保证安全和产品的质量,每台机器最多只能连续完成产品的L个步骤.也就是说,如果有一台机器连续完

单调队列

先放上luogu的题目链接--滑稽窗口 然后我们再来讲单调队列 单调队列是指这样一种队列:在队列中的元素为单调递增状态或单调递减状态. 例如1 2 3 4 5和9 2 1都是单调队列,但1 2 2 3 4和4 3 4 5就不是单调队列. 但普通队列明显是维持不了单调队列的性质的. 为了维持单调队列的单调性质,我们只好想一些方法.方法就是修改队列的性质.单调队列不仅队头可以出队,队尾也可以出队. 比如说有一个单调队列是 1 3 7 8 现在突然要从队尾进来一个6如果单纯的把6插进队尾的话,那这个队

单调队列 BZOJ 2096 [Poi2010]Pilots

2096: [Poi2010]Pilots Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 819  Solved: 418[Submit][Status][Discuss] Description Tz又耍畸形了!!他要当飞行员,他拿到了一个飞行员测试难度序列,他设定了一个难度差的最大值,在序列中他想找到一个最长的子串,任意两个难度差不会超过他设定的最大值.耍畸形一个人是不行的,于是他找到了你. Input 输入:第一行两个有空格隔开的整数k(0

HDU 3706 Second My Problem First (单调队列)

题意:求给定的一个序列中最长子序列,该子序列的最大值和最小值介于m和k之间. 析:用两个单调队列来维护一个最小值,一个最大值,然后每次更新即可. 代码如下; #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <i

codevs3327选择数字(单调队列优化)

3327 选择数字 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 给定一行n个非负整数a[1]..a[n].现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择.你的任务是使得选出的数字的和最大. 输入描述 Input Description 第一行两个整数n,k 以下n行,每行一个整数表示a[i]. 输出描述 Output Description 输出一个值表示答案. 样例输入 Sample Input 5 2