志愿者选拔(单调队列)

Problem 1894 志愿者选拔

Accept: 1783    Submit: 5564 Time Limit: 1500 mSec    Memory Limit : 32768 KB

 Problem Description

世博会马上就要开幕了,福州大学组织了一次志愿者选拔活动。参加志愿者选拔的同学们排队接受面试官们的面试。参加面试的同学们按照先来先面试并且先结束的原则接受面试官们的考查。面试中每个人的人品是主要考查对象之一。(提高人品的方法有扶老奶奶过街,不闯红灯等)作为主面试官的John想知道当前正在接受面试的同学队伍中人品值最高的是多少。于是他请你帮忙编写一个程序来计算。

 Input

输入数据第一行为一整数T,表示有T组输入数据。每组数据第一行为”START”,表示面试开始接下来的数据中有三种情况:

  输入 含义
1 C NAME RP_VALUE 名字为NAME的人品值为RP_VALUE的同学加入面试队伍。(名字长度不大于5,0 <= RP_VALUE <= 1,000,000,000)
2 G 排在面试队伍最前面的同学面试结束离开考场。
3 Q 主面试官John想知道当前正在接受面试的队伍中人品最高的值是多少。

最后一行为”END”,表示所有的面试结束,面试的同学们可以依次离开了。所有参加面试的同学总人数不超过1,000,000

 Output

对于每个询问Q,输出当前正在接受面试的队伍中人品最高的值,如果当前没有人正在接受面试则输出-1。

 Sample Input

2 START C Tiny 1000000000 C Lina 0 Q G Q END START Q C ccQ 200 C cxw 100 Q G Q C wzc 500 Q END

 Sample Output

1000000000 0 -1 200 100 500

 Hint

数据较大建议使用scanf,printf 不推荐使用STL

题解:set+queue超时, 其实是个单调队列。。。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<stack>
#include<set>
#include<queue>
using namespace std;
/*
struct Node{
    char name[6];
    int rp_value;
    friend bool operator < (Node a, Node b){
            return a.rp_value > b.rp_value;
    }
};
set<Node>st;
set<Node>::iterator iter;
queue<Node>Q;
int main(){
    char s[6];
    int tp_value, T;

    scanf("%d", &T);
    while(T--){
        while(!Q.empty())Q.pop();
        st.clear();
        scanf("%s", s);
        int tp = 0, cur = 0;
        while(scanf("%s", s), strcmp(s, "END")){
            if(s[0] == ‘C‘){
                Node a;
                scanf("%s%d", a.name, &a.rp_value);
                st.insert(a);
                Q.push(a);
            }
            else if(s[0] == ‘Q‘){
                if(st.empty())
                    puts("-1");
                else
                    printf("%d\n", st.begin()->rp_value);
            }
            else if(s[0] == ‘G‘ && !Q.empty()){
                iter = st.find(Q.front());
                if(iter != st.end())st.erase(iter);
                Q.pop();
            }
        }
    }
    return 0;
}
*/
struct Node{
    int cur;
    char name[6];
    int rp;
};
Node Q[1000100];
int main(){
    char s[6];
    int T;
    scanf("%d", &T);
    while(T--){
        scanf("%s", s);
        int head, tail;
        head = 0;tail = -1;
        int cur = 0, Gcur= 0;
        while(scanf("%s", s), strcmp(s, "END")){
            if(s[0] == ‘C‘){
                Node a;
                scanf("%s%d", a.name, &a.rp);
                a.cur = ++cur;
                while(head <= tail &&(tail == -1 || Q[tail].rp <= a.rp))
                    tail--;
                Q[++tail] = a;
            }
            else if(s[0] == ‘Q‘){
                if(head > tail)
                    puts("-1");
                else
                    printf("%d\n", Q[head].rp);
            }
            else if(s[0] == ‘G‘){
                Gcur++;
                if(head <= tail && Gcur == Q[head].cur)
                    head++;
            }
        }
    }
    return 0;
}
时间: 2024-08-28 06:38:41

志愿者选拔(单调队列)的相关文章

FZU 1894 志愿者选拔 单调队列

训练赛的题…… 暴力一波明显超时…… 最近刚学stl 感觉是优先队列 但还是太会用…… 以后可以试一下优先队列…… 比赛之后百度了一下 发现是单调队列…… 看起来挺简单的 也算个模版题吧…… 总之思路就是维护一个单调队列…… 有用的的只有C G Q…… 那个长度最多是5的名字只用接着 根本没用…… 直接上代码…… #include<stdio.h> #include<iostream> #include<string.h> #include<algorithm&g

FZU 1894 志愿者选拔【单调队列】【monotone decreasing queue】

?Problem 1894 志愿者选拔 Accept: 1770????Submit: 5523 Time Limit: 1500 mSec????Memory Limit : 32768 KB ?Problem Description 世博会立即就要开幕了,福州大学组织了一次志愿者选拔活动.參加志愿者选拔的同学们排队接受面试官们的面试.參加面试的同学们依照先来先面试而且先结束的原则接受面试官们的考查.面试中每一个人的人品是主要考查对象之中的一个.(提高人品的方法有扶老奶奶过街,不闯红灯等)作为

暑期训练狂刷系列——Foj 1894 志愿者选拔 (单调队列)

题目连接: http://acm.fzu.edu.cn/problem.php?pid=1894 解题思路: 因为出队和入队都满足队列的性质,优先单调队列的优先级有进入队列的顺序和人品的高低,在一段区间中如果出现x[i]是最大的,那么[0,i-1]区间内的数就不用记录了,所以单调队列里面可以按照人品值降序排列,输出的时候判断一下当前元素是否已经出队即可. 1 #include <cstdio> 2 #include <cstring> 3 using namespace std;

单调栈/单调队列/RMQ

在上上周的交友大会中,队长大人提到了st算法,然后仔细的发呆了一个星期,于是就开始做队长的专题了, 6天后的我总算在此专题做题数目和队长一样了..明早没课,准备通宵把这几天的零散的记忆整理一下. HDU 3530 Subsequence 一开始想为何不能m和k一起放到while语句里进行处理 nowmax和nowmin保存了i之前的最大和最小值,假设此时已经出现不满足k和m的序列(A)了(比k大or比m小or both),然后我们往后找,发现了一个比序列(A)的min更小的值(me),此时now

fzu 1894 单调队列

http://acm.fzu.edu.cn/problem.php?pid=1894  Problem 1894 志愿者选拔 Accept: 1328    Submit: 4200Time Limit: 1500 mSec    Memory Limit : 32768 KB  Problem Description 世博会马上就要开幕了,福州大学组织了一次志愿者选拔活动.参加志愿者选拔的同学们排队接受面试官们的面试.参加面试的同学们按照先来先面试并且先结束的原则接受面试官们的考查.面试中每个

【UOJ 55】志愿者选拔

[题目描述]: 世博会马上就要开幕了,福州大学组织了一次志愿者选拔活动. 参加志愿者选拔的同学们排队接受面试官们的面试.参加面试的同学们按照先来先面试并且先结束的原则接受面试官们的考查. 面试中每个人的人品是主要考查对象之一.(提高人品的方法有扶老奶奶过街,不闯红灯等) 作为主面试官的John想知道当前正在接受面试的同学队伍中人品值最高的是多少.于是他请你帮忙编写一个程序来计算. [输入描述]: 输入数据第一行为一整数T,表示有T组输入数据. 每组数据第一行为”START”,表示面试开始 接下来

【动态规划】【单调队列】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个步骤.也就是说,如果有一台机器连续完