手动建栈维护最大值,用两个栈模拟队列!!

本文介绍了一种解决大规模队列极值问题的方法,通过使用两个栈来模拟队列的操作,实现高效的最大值和最小值查询。适用于数据结构与算法的学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

J.队列极值

时间限制: 1000ms 内存限制: 65535KB
通过次数: 6总提交次数: 58
问题描述
转眼间【HuJie】在灵隐寺待了将近半年,别说和日剧里的和尚似的泡到妹子结婚,就是连妹子的人影都见不着。好歹我们【HuJie】也是一表人才,英俊潇洒的,怎么能孤独终老呢?他才明白日剧里都是骗人的,还是回去好好的念书吧。但是,【HuJie】偷偷出家的日子里已经旷了不少课了,所幸没有被学校查课给查出来,于是又偷偷溜回来上课了。但是实验室的【潘老师】可不会这么容易就放过贪玩的【HuJie】,他因为实验室的事情忙得不行,却到处找不着【HuJie】,这回【HuJie】自己溜回来了。于是【潘老师】对【HuJie】说:“这样吧,你做一道《数据结构》的队列题,要是做出来了,我就不追究你了。不过这次的数据量有点儿大,可要好好想想怎么做。”聪明的你能帮帮他吗?
输入描述
输入包含多组数据,每组数据以一个正整数n(1≤n≤5×〖10〗^5)开始,表示之后共有n次队列操作,之后n行每行包含一个操作。入队操作为”ENQUEUE x”,其中0≤x≤〖10〗^9表示将元素x入队;出队操作为”DEQUEUE”;询问操作为”MAX”或”MIN”,分别表示询问当前队列中的最大值或最小值。输入数据以0结束。
输出描述
对应每一组输入数据,第一行输出”Case #:”表示第#组数据,之后对每一次出队操作返回当前出队的元素,对每一次询问操作输出恰当的结果,若队列为空则输出”EMPTY!”,每次输出占一行。
样例输入
3
ENQUEUE 1
MAX
DEQUEUE
5
ENQUEUE 2
MAX
DEQUEUE
MIN
DEQUEUE
0
样例输出
Case 1:
1
1
Case 2:
2
2
EMPTY!
EMPTY!
手动建栈维护最大值,用两个栈模拟队列!!
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
char str[20];
class Stack
{
public:
    void clear()
    {
        stacktop=-1;
        maxitem=-1;
        minitem=-1;
    }
    void push(int x)
    {
        stacktop++;
        stackitem[stacktop]=x;
        if(x>max())
        {
            linkmax[stacktop]=maxitem;
            maxitem=stacktop;
        }
        else
            linkmax[stacktop]=-1;
        if(x<min())
        {
            linkmin[stacktop]=minitem;
            minitem=stacktop;
        }
        else
            linkmin[stacktop]=-1;
    }
    int pop()
    {
        int res=stackitem[stacktop];
        if(stacktop==maxitem)
        {
            maxitem=linkmax[stacktop];
        }
        if(stacktop==minitem)
        {
            minitem=linkmin[stacktop];
        }
        stacktop--;
        return res;
    }
    int max()
    {
        if(maxitem>=0)
            return stackitem[maxitem];
        else
            return -1;
    }
    int min()
    {
        if(minitem>=0)
            return stackitem[minitem];
        else
            return INF;
    }
    bool empty()
    {
        if(stacktop>=0)
            return false;
        return true;
    }
private:
    int stackitem[500010];
    int stacktop;
    int linkmax[500010];
    int linkmin[500010];
    int maxitem;
    int minitem;
};

class Queue
{
public:
    void clear()
    {
        stacka.clear();
        stackb.clear();
    }
    int maxvalue(int x,int y)
    {
        return x>y?x:y;
    }
    int minvalue(int x,int y)
    {
        return x>y?y:x;
    }
    int max()
    {
        if(stacka.empty()&&stackb.empty())
            return -1;
        return maxvalue(stacka.max(),stackb.max());
    }
    int min()
    {
        if(stacka.empty()&&stackb.empty())
            return -1;
        return minvalue(stacka.min(),stackb.min());
    }
    void push(int x)
    {
        stackb.push(x);
    }
    int pop()
    {
        if(stacka.empty())
        {
            while(!stackb.empty())
            {
                stacka.push(stackb.pop());
            }
        }
        if(stacka.empty())
            return -1;
        return stacka.pop();
    }
private:
    Stack stacka;
    Stack stackb;
};
Queue q;
int main()
{
    int n,ca=1,x;
    while(scanf("%d",&n)!=EOF&&n)
    {
        printf("Case %d:\n",ca++);
        q.clear();
        while(n--)
        {
            scanf("%s",str);
            if(str[1]=='N')
            {

                scanf("%d",&x);
                q.push(x);
            }
            else if(str[1]=='E')
            {
                int res=q.pop();
                if(res!=-1)
                    printf("%d\n",res);
                else
                    printf("EMPTY!\n");
            }
            else if(str[1]=='A')
            {
                int res=q.max();
                if(res!=-1)
                    printf("%d\n",res);
                else
                    printf("EMPTY!\n");
            }
            else
            {
                int res=q.min();
                if(res!=-1)
                    printf("%d\n",res);
                else
                    printf("EMPTY!\n");
            }
        }
    }
    return 0;
}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值