UVA - 12096 :The SetStack Computer
题目大意
用集合模拟计算机操作。每执行完一个操作,输出栈顶的集合大小,操作如下:
PUSH:空集合压栈DUP:将栈顶元素再次压栈UNION:依次弹栈得a,b,求并集后压栈INTERSECT:依次弹栈得a,b,求交集后压栈ADD:依次弹栈得a,b,将a作为一个元素加入b中
思路分析
很好的一道题目,关键在于如何设计递归定义的集合的数据结构,只要能判定两个集合异同即可
初步尝试
- 很自然想到用哈希映射,根据括号和逗号位置,用类似N进制方法计算出一个值,但无奈递归定义的集合个数无限,无法使用此方法
- 于是想用字符串直接模拟括号和逗号序列,但也过于麻烦
巧妙参考
之前尝试总体思路是对的,均是为了找到一个集合的唯一标识,但不可用函数关系映射方式,这里可用手动构造id方式分配唯一标识,因为递归定义的个数无限,找不到规律且空间有限,只可手动构造,类似malloc申请分配地址。
因此,模仿递归定义设计数据结构,给每个集合分配编号,然后集合中存储已有集合编号,即可实现递归定义
vector<set<int> > setCache; // 哈希表:集合id->集合
map<set<int>, int> setToId; // 映射:集合->id
stack<int>stk; // 栈模拟处理过程,存储集合id
核心实现在于id分配算法,其实现如下,若已有该集合,直接返回id;否则,分配一个新id
int getSetId(const set<int>& _set) { // 获取set对应id,不存在则新分配一个
if (setToId.find(_set) != setToId.end()) return setToId[_set]; // 存在
setCache.push_back(_set); // 不存在则分配
return setToId[_set] = setCache.size() - 1; // id/位置标号
}
至于集合的交并操作可用algorithm中的set_union,set_intersection实现,注意其第五个参数是构造一个存储插入的迭代器,inserter是特殊的插入迭代器,父类为iterator,t和t.begin()分别表示存储结果的容器和开始位置
set_union(a.begin(),a.end(),b.begin(),b.end(),inserter(t,t.begin())); // 并集:a U b -> t
set_intersection(a.begin(),a.end(),b.begin(),b.end(),inserter(t,t.begin())); // a交b -> t
注意点
- set_union和set_intersection的使用,注意第五个参数构造
- 手动分配id可实现递归定义
AC代码(C++11,手动分配id,集合交并,栈模拟)
#include<bits/stdc++.h>
using namespace std;
vector<set<int> > setCache; // 哈希表:集合id->集合
map<set<int>, int> setToId; // 映射:集合->id
int T, n;
string cmd;
int getSetId(const set<int>& _set) { // 获取set对应id,不存在则新分配一个
if (setToId.find(_set) != setToId.end()) return setToId[_set]; // 存在
setCache.push_back(_set); // 不存在则分配
return setToId[_set] = setCache.size() - 1; // id/位置标号
}
int main() {
cin >>T;
while (T --) {
cin >>n;
stack<int> stk; setCache.clear(); setToId.clear(); // 初始化
while (n --) {
cin >>cmd;
if (cmd == "PUSH") stk.push(getSetId(set<int>())); // 空
else if (cmd == "DUP") stk.push(stk.top()); // 重复
else {
set<int> t, a, b;
a = setCache[stk.top()]; stk.pop();
b = setCache[stk.top()]; stk.pop();
if (cmd == "UNION") set_union(a.begin(),a.end(),b.begin(),b.end(),inserter(t,t.begin()));
if (cmd == "INTERSECT") set_intersection(a.begin(),a.end(),b.begin(),b.end(),inserter(t,t.begin()));
if (cmd == "ADD") t = b, t.insert(setToId[a]);
stk.push(getSetId(t));
}
printf("%d\n", setCache[stk.top()].size());
}
puts("***");
}
return 0;
}
UVA - 12096 :The SetStack Computer的更多相关文章
- UVa 12096 (STL) The SetStack Computer
题意: 有一个集合栈计算机,栈中的元素全部是集合,还有一些相关的操作.输出每次操作后栈顶集合元素的个数. 分析: 这个题感觉有点抽象,集合还能套集合,倒是和题中配的套娃那个图很贴切. 把集合映射成ID ...
- 【例题5-5 UVA 12096 】The SetStack Computer
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 用set来解决这个问题. 考虑如何表示 { {{}} }这个集合 我们可以把{}这个集合和一个数字映射->1 然后把1加入到某 ...
- UVA.12096 The SetStack Computer ( 好题 栈 STL混合应用)
UVA.12096 The SetStack Computer ( 好题 栈 STL混合应用) 题意分析 绝对的好题. 先说做完此题的收获: 1.对数据结构又有了宏观的上的认识; 2.熟悉了常用STL ...
- uva 12096 The SetStack Computer
点击打开链接uva 12096 思路: STL模拟 分析: 1 题目给定5种操作,每次输出栈顶集合的元素的个数 2 利用stack和set来模拟,set保存集合的元素.遇到push的时候直接在stac ...
- 12096 - The SetStack Computer UVA
Background from Wikipedia: \Set theory is a branch of mathematics created principally by the German ...
- EOJ 1641/UVa The SetStack Computer
Background from Wikipedia: “Set theory is a branch of mathematics created principally by the German ...
- UVa12096.The SetStack Computer
题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- 集合栈计算机(The SetStack Computer, ACM/ICPC NWERC 2006,Uva12096)
集合栈计算机(The SetStack Computer, ACM/ICPC NWERC 2006,Uva12096) 题目描述 有一个专门为了集合运算而设计的"集合栈"计算机.该 ...
- UVA12096 - The SetStack Computer(set + map映射)
UVA12096 - The SetStack Computer(set + map映射) 题目链接 题目大意:有五个动作: push : 把一个空集合{}放到栈顶. dup : 把栈顶的集合取出来, ...
- uva 12096 - The SetStack Computer(集合栈)
例题5-5 集合栈计算机(The Set Stack Computer,ACM/ICPC NWERC 2006,UVa12096) 有一个专门为了集合运算而设计的"集合栈"计算机. ...
随机推荐
- 再学Blazor——组件建造者
使用 RenderTreeBuilder 创建组件是 Blazor 的一种高级方案.前几篇文中有这样创建组件的示例 builder.Component<MyComponent>().Bui ...
- notify为什么会引发超时,notify和notifyAll的区别
notify为什么会引发超时,notify和notifyAll的区别 每个同步对象都有对应的monitor,首先了解下monitor的内部结构. 1.monitor结构 Owner:指向拥有该同步对象 ...
- springboot实现反向代理,动态代理目标地址
网上找了很多文章,各种照搬,只能自己实现 基于开源项目HTTP-Proxy-Servlet实现 开源项目地址:https://github.com/mitre/HTTP-Proxy-Servlet 1 ...
- ConcurrentModificationException日志关键字报警引发的思考
本文将记录和分析日志中的ConcurrentModificationException关键字报警,还有一些我的思考,希望对大家有帮助. 一.背景 近期,在日常的日志关键字报警分析时,发现我负责的一个电 ...
- [CF1849F] XOR Partition
XOR Partition 题目描述 For a set of integers $ S $ , let's define its cost as the minimum value of $ x \ ...
- C++ Qt开发:StatusBar底部状态栏组件
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍QStatus ...
- Critical error detected c0000374
我发现出现上述错误是 free 两次内存 float* dd=new float[2]; delete[] dd; delete[] dd;
- Selenium接管已经打开的浏览器并爬取数据
""" P.S:需要接管现有浏览器 ** 使用步骤: 1.打开浏览器,设置好远程调试端口,并扫描登录淘宝. chrome.exe --remote-debugging-p ...
- Java使用HttpUtil.request方法可以发送请求即【Java访问url得到响应数据】
Java使用HttpUtil.request方法可以发送请求即[Java访问url得到响应数据] 注:这个工具类可以在网上找,也可以自己手写 ,手写的话需要用到以下依赖: <dependency ...
- int和String的相互转换