【传送门】http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4016
【题目大意】初始有n个空栈,现在有如下三种操作:
(1) 1 s v 即 s.push(v)
(2) 2 s 即 s.pop() 输出弹出的元素,如果栈s为空则输出 "EMPTY"
(3) 3 s t 把t栈元素全部移到s栈中,使s的尾部与t的首部相连。
现在有若干上述三种类型的操作,遇到操作2则输出相应内容。
【题解】由于站的数量n和操作次数q的数量级都达到1e5,建这么多栈取模拟上述三种操作是不明智的,特别是对于操作2,还要设置一个辅助栈来把元素按序移动到s栈。其实看到操作2就应该想到这应该是用链表实现,而且是双向链表,时间复杂度O(1)
核心方法调用:
assign() 给list赋值
back() 返回最后一个元素
begin() 返回指向第一个元素的迭代器
clear() 删除所有元素
empty() 如果list是空的则返回true
end() 返回末尾的迭代器
erase() 删除一个元素
front() 返回第一个元素
get_allocator() 返回list的配置器
insert() 插入一个元素到list中
max_size() 返回list能容纳的最大元素数量
merge() 合并两个list
pop_back() 删除最后一个元素
pop_front() 删除第一个元素
push_back() 在list的末尾添加一个元素
push_front() 在list的头部添加一个元素
rbegin() 返回指向第一个元素的逆向迭代器
remove() 从list删除元素
remove_if() 按指定条件删除元素
rend() 指向list末尾的逆向迭代器
resize() 改变list的大小
reverse() 把list的元素倒转
size() 返回list中的元素个数
sort() 给list排序
splice() 合并两个list
swap() 交换两个list
unique() 删除list中重复的元素
【代码】
#include <iostream> #include <cstring> #include <string> #include <cstdio> #include <list> using namespace std; #define maxsize 300005 list <int> st[maxsize]; int main() { int cas; scanf("%d",&cas); while(cas--) { for(int i=0;i<maxsize;i++) { st[i].clear(); } int n,q; scanf("%d%d",&n,&q); int a,b,c; while(q--) { scanf("%d",&a); if(a == 1) { scanf("%d%d",&b,&c); st[b].push_back(c); } if(a == 2) { scanf("%d",&b); if(st[b].empty()) { printf("EMPTY\n"); } else { printf("%d\n",st[b].back()); st[b].pop_back(); } } if(a == 3) { scanf("%d%d",&b,&c); st[b].splice(st[b].end(),st[c]); } } } return 0; }
原文地址:https://www.cnblogs.com/czsharecode/p/9606564.html