• 2016 多校联赛7 Joint Stacks (优先队列)


    A stack is a data structure in which all insertions and deletions of entries are made at one end, called the "top" of the stack. The last entry which is inserted is the first one that will be removed. In another word, the operations perform in a Last-In-First-Out (LIFO) manner. 
    A mergeable stack is a stack with "merge" operation. There are three kinds of operation as follows: 

    - push A x: insert x into stack A 
    - pop A: remove the top element of stack A 
    - merge A B: merge stack A and B 

    After an operation "merge A B", stack A will obtain all elements that A and B contained before, and B will become empty. The elements in the new stack are rearranged according to the time when they were pushed, just like repeating their "push" operations in one stack. See the sample input/output for further explanation.
    Given two mergeable stacks A and B, implement operations mentioned above. 

    InputThere are multiple test cases. For each case, the first line contains an integer N(0<N105)N(0<N≤105), indicating the number of operations. The next N lines, each contain an instruction "push", "pop" or "merge". The elements of stacks are 32-bit integers. Both A and B are empty initially, and it is guaranteed that "pop" operation would not be performed to an empty stack. N = 0 indicates the end of input.OutputFor each case, print a line "Case #t:", where t is the case number (starting from 1). For each "pop" operation, output the element that is popped, in a single line.Sample Input

    4
    push A 1
    push A 2
    pop A
    pop A
    9
    push A 0
    push A 1
    push B 3
    pop A
    push A 2
    merge A B
    pop A
    pop A
    pop A
    9
    push A 0
    push A 1
    push B 3
    pop A
    push A 2
    merge B A
    pop B
    pop B
    pop B 
    0

    Sample Output

    Case #1:
    2
    1
    Case #2:
    1
    2
    3
    0
    Case #3:
    1
    2
    3
    0

    启发博客:http://www.cnblogs.com/Sunshine-tcf/p/5753964.html
    用三个优先队列来维护,最神奇的是,由于题目说POP操作不会对空栈进行,甚至不需要对C这个公共栈标记是A或是B。
    详见下:

    题意:


    给出两个栈A B(初始时为空),有三种操作:
    push、pop、merge.
    其中merge是按照A B中元素进栈的相对顺序来重排的.

    题解:


    给每次push的数加上一个时间戳.
    维护三个优先队列,按照节点的进栈时间从后往前排序(时间戳从大往小). 这样就保证了列首元素一定是最晚进栈的.
    三个优先队列:A和B为题中的栈,COM为公共栈. (即存放合并后的结果,并标记COM当前是A还是B)
    ①对于push操作,按照正常逻辑入栈(入队).
    ②对于pop操作,先从A/B中去找,如果A/B为空,则说明存放在COM公共栈中了.
    (题目保证了不会对空栈pop,这样一来都不需要再额外标记公共栈COM当前是A还是B了).
    ③对于merge操作,把当前A和B全部清空并放到公共栈COM中即可.
    可以证明,每个元素被移动到COM中的次数不超过1. 所以总体时间复杂度还是O(n).

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<queue>
     4 #include<vector>
     5 using namespace std;
     6 
     7 struct node
     8 {
     9     int num,t;//t表示入栈时间
    10     node(int a,int b){
    11         num=a;t=b;
    12     }//构造函数用于在队列中插入结构体
    13 };
    14 
    15 struct cmp//queue的比较函数
    16 {
    17     bool operator()(node a,node b)
    18     {
    19         return a.t<b.t;//top是入栈最晚的,后进先出
    20     }
    21 };
    22 
    23 int main()
    24 {
    25     int n,c,i,T=1;
    26     char a[10],b;
    27     while(~scanf("%d",&n)&&n)
    28     {
    29         printf("Case #%d:
    ",T++);
    30         priority_queue<node,vector<node>,cmp>A,B,C;
    31         for(i=0;i<n;i++)
    32         {
    33             cin>>a;
    34             if(a[1]=='u')//push操作
    35             {
    36                 cin>>b>>c;
    37                 if(b=='A')
    38                     A.push(node(c,i));
    39                 else
    40                     B.push(node(c,i));
    41             }
    42             else if(a[1]=='o')//pop操作
    43             {
    44                 cin>>b;
    45                 if(b=='A'&&!A.empty())
    46                 {
    47                     printf("%d
    ",A.top().num);
    48                     A.pop();
    49                 }
    50                 else if(b=='B'&&!B.empty())
    51                 {
    52                     printf("%d
    ",B.top().num);
    53                     B.pop();
    54                 }
    55                 else
    56                 {
    57                     printf("%d
    ",C.top().num);
    58                     C.pop();
    59                 }
    60 
    61             }
    62             else//merge操作
    63             {
    64                 cin>>b>>b;
    65                 while(!A.empty())
    66                 {
    67                     C.push(A.top());
    68                     A.pop();
    69                 }
    70                 while(!B.empty())
    71                 {
    72                     C.push(B.top());
    73                     B.pop();
    74                 }
    75             }
    76         }
    77     }
    78     return 0;
    79 }
  • 相关阅读:
    WPF中的句柄
    WPF中的焦点问题
    Vue项目(一):VSCode环境开发Vue程序以及其中遇到的问题
    C#实现三种方式的模拟按键
    c++温故之结构体写法
    WPF搜索框
    vue框架学习
    Git连接失败问题解决方案
    单击双击冲突解决 小程序
    uniapp 微信小程序 wx.createAnimation 实现向上滚动弹幕
  • 原文地址:https://www.cnblogs.com/Annetree/p/7169957.html
Copyright © 2020-2023  润新知