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) 有一个专门为了集合运算而设计的"集合栈"计算机. ...
随机推荐
- js判断字符串数据类型
mounted() { this.isJSON('{"key":1232,"a":2},{"key":1232,"a": ...
- 手把手教Electron+vue,打包vue项目,打包成桌面程序。
1.现如今前端框架数不胜数,尤其是angular.vue吸引一大批前端开发者,在这个高新技术快速崛起的时代,自然少不了各种框架的结合使用.接下来是介绍electron+vue的结合使用. 2.Elec ...
- Educational Codeforces Round 101 (Rated for Div. 2) E - A Bit Similar
题目传送门 很巧妙的一道题.对于一个 \(n\)位的 \(01\)字符串,一共有 \(2^n\)种不同字符排列,对于任意一个固定排列,在 \(2^n\)种排列中只有一种排列与该固定排列处处不等,而题干 ...
- 吉特日化MES实施--三种浪费
在实施吉特日化MES系统的过程中,遇到各种问题,包括自身问题以及甲方问题,导致项目滞后延期的主要问题分析,汇总三种浪费: (1) 信息传递的浪费: 这个在甲方产品设计以及生产过程中出现的问题,也是我 ...
- [USACO2007NOVG] Cow Relays G
题目描述 For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a relay race ...
- [ABC263F] Tournament
Problem Statement $2^N$ people, numbered $1$ to $2^N$, will participate in a rock-paper-scissors tou ...
- SpringCloudGateway解决跨域问题
1.跨域问题详情 2.为什么会跨域? 官方定义:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS 怎么出现的? 1.浏览器访问了一个业务 h ...
- Stream API学习笔记
Java8 中Stream API介绍 Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象.这种风格将要处理的元素集合看作一种流, ...
- pytest框架学习-标签@pytest.mark.
标签 自定义标签(区分大小写) 可以标记测试用例,对测试用例进行分组,有利于对测试用例进行筛选. 比如:给用例打标为API,代表接口自动化的用例,打标方法为@pytest.mark.API,打标后,需 ...
- 免费背景音人声分离解决方案MVSEP-MDX23,足以和Spleeter分庭抗礼
在音视频领域,把已经发布的混音歌曲或者音频文件逆向分离一直是世界性的课题.音波混合的物理特性导致在没有原始工程文件的情况下,将其还原和分离是一件很有难度的事情. 言及背景音人声分离技术,就不能不提Sp ...