HDU 5818 (多校 7) 模拟

本文介绍了一种关于栈操作的问题解决方法,通过引入第三个栈来进行合并操作,并保持元素按时间顺序排列。讨论了如何高效地执行入栈、出栈及合并栈操作,并提供了具体的实现代码。

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

题意:对栈的操作,有两个栈ab然后接下来n组操作包括入栈,出栈,合并栈。合并栈按入栈的时间顺序进行排序。

官方题解:比较简单巧妙的一个做法是引入一个新的栈C,每次合并的时候就把AB合并到C上,然后把AB都清空. push还是按正常做,pop注意当遇到要pop的栈为空时,因为题目保证不会对空栈进行pop操作,所以这时应直接改为对C栈进行pop操作. 这样做因为保证每个元素最多只在一次合并中被处理到,pop和push操作当然也是每个元素只做一次,所以总复杂度是O(N)的. 另一种做法是用链表来直接模拟,复杂度也是O(N),但代码量稍大一些.

解题思路:比赛时怎么想都想不出来,一直只想着是要合并两个栈,但强行排序肯定是会TLE的,看了题解之后才知道原来这么简单,还是自己太弱了。直接用三个数组进行模拟了一下。

AC代码:

#include <iostream>
#include <stdio.h>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <stack>


using namespace std;
#define ll long long
#define maxn 100050

struct test
{
    int  val;
    int  pos;
};

test a[maxn];
test b[maxn];
test c[maxn];

int main()
{
    int n;
    char str1[10];
    char str2[5];
    char str3[5];
    int cas=1;
    int num;
    int ida,idb,idc;
    while(~scanf("%d",&n) && n!=0)
    {
        ida=0;
        idb=0;
        idc=0;
        int cnt=1;///表示入栈的时间
        printf("Case #%d:\n",cas++);
        for(int i=0;i<n;i++)
        {
            scanf("%s%s",str1,str2);
            if(str1[1]=='u')///入队操作
            {
                scanf("%d",&num);
                if(str2[0]=='A')
                {
                    a[ida].val=num;
                    a[ida++].pos=cnt++;
                }
                else
                {
                    b[idb].val=num;
                    b[idb++].pos=cnt++;
                }
            }
            else if(str1[1]=='e')///合并操作
            {
                scanf("%s",str3);
                int ia=0,ib=0;
                while(ia<ida&&ib<idb)
                {
                    if(a[ia].pos<b[ib].pos)///比较a,b栈中时间小的入栈
                    {
                        c[idc].pos=a[ia].pos;
                        c[idc++].val=a[ia++].val;
                    }
                    else
                    {
                        c[idc].pos=b[ib].pos;
                        c[idc++].val=b[ib++].val;
                    }
                }
                while(ia<ida)
                {
                    c[idc].pos=a[ia].pos;
                    c[idc].val=a[ia++].val;
                    idc++;
                }
                while(ib<idb)
                {
                    c[idc].pos=b[ib].pos;
                    c[idc++].val=b[ib++].val;
                }
                ida=0; idb=0;
            }
            else if(str1[1]=='o')///出队操作
            {
                if(str2[0]=='A')
                {
                    if(ida==0)
                        printf("%d\n",c[--idc].val);
                    else
                        printf("%d\n",a[--ida].val);
                }
                else
                {
                    if(idb==0)
                        printf("%d\n",c[--idc].val);
                    else
                        printf("%d\n",b[--idb].val);
                }
            }
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值