HDU5818 - 合并栈操作
HDU5818 - 合并栈操作
题设
【问题描述】
栈是一种具有后进先出的数据结构。可合并栈是支持“merge”操作的栈。三种操作的说明如下:
① push A x:将x插入栈A中。
② pop A:删除栈A的顶部元素。
③ merge A B:合并栈A和B。
其中,“merge A B”操作后栈A包含A和B之前的所有元素,B变为空,新栈中的元素根据先前的进栈时间重新排列,就像在一个栈中重复”push”操作一样。给定两个可合并栈A和B,请执行上述操作。
【输入形式】
测试用例的第一行包含一个整数n(0<n≤10^5)表示操作个数,接下来的n行每行包含一条指令push、pop或merge,栈元素是32位整数。A和B最初都是空的,并且保证不会对空栈执行pop操作。以n=0表示输入结束。
【输出形式】
对于每个pop操作,在一行中输出对应的出栈元素。
【样例输入】
9
push A 0
push A 1
push B 3
pop A
push A 2
merge A B
pop A
pop A
pop A
【样例输出】
1
2
3
0
题解
本题是作者数据结构与算法课上的一道习题,主要难点在于记录每一个数据的时间戳,以便merge操作的比较。作者使用了非常直接的办法,即将数据和时间戳用一个pair来记录,并为其单独写了一个comp比较函数,作为sort函数的传参。每次merge操作时,将A和B中的元素都弹出至vector中,并根据时间戳排序,再全部压入栈中。考虑到该题对算法的性能要求不高,该法可以达到目的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <algorithm>
#include <iostream>
#include <stack>
#include <string>
#include <vector>
using namespace std;
stack<pair<int, int>> A;
stack<pair<int, int>> B;
bool comp(const pair<int, int>& p1, const pair<int, int>& p2) {
return p1.first < p2.first;
}
void merge(stack<pair<int, int>>& s1, stack<pair<int, int>>& s2) {
vector<pair<int, int>> v;
while (!s1.empty()) {
v.push_back(s1.top());
s1.pop();
}
while (!s2.empty()) {
v.push_back(s2.top());
s2.pop();
}
sort(v.begin(), v.end(), comp);
for (auto i : v) {
s1.push(i);
}
}
int main() {
// freopen("in.txt", "r", stdin);
int n, m = 0;
cin >> n;
cin.ignore();
while (n--) {
string line;
getline(cin, line);
switch (line[1]) {
case 'u':
if (line[5] == 'A') {
A.push(make_pair(m++, line[7] - '0'));
} else {
B.push(make_pair(m++, line[7] - '0'));
}
break;
case 'o':
if (line[4] == 'A') {
cout << A.top().second << endl;
A.pop();
} else {
cout << B.top().second << endl;
B.pop();
}
break;
case 'e':
if (line[6] == 'A') {
merge(A, B);
} else {
merge(B, A);
}
break;
}
}
return 0;
}
This post is licensed under CC BY 4.0 by the author.