题目大意

用集合模拟计算机操作。每执行完一个操作,输出栈顶的集合大小,操作如下:

  • 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是特殊的插入迭代器,父类为iteratort和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的更多相关文章

  1. UVa 12096 (STL) The SetStack Computer

    题意: 有一个集合栈计算机,栈中的元素全部是集合,还有一些相关的操作.输出每次操作后栈顶集合元素的个数. 分析: 这个题感觉有点抽象,集合还能套集合,倒是和题中配的套娃那个图很贴切. 把集合映射成ID ...

  2. 【例题5-5 UVA 12096 】The SetStack Computer

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 用set来解决这个问题. 考虑如何表示 { {{}} }这个集合 我们可以把{}这个集合和一个数字映射->1 然后把1加入到某 ...

  3. UVA.12096 The SetStack Computer ( 好题 栈 STL混合应用)

    UVA.12096 The SetStack Computer ( 好题 栈 STL混合应用) 题意分析 绝对的好题. 先说做完此题的收获: 1.对数据结构又有了宏观的上的认识; 2.熟悉了常用STL ...

  4. uva 12096 The SetStack Computer

    点击打开链接uva 12096 思路: STL模拟 分析: 1 题目给定5种操作,每次输出栈顶集合的元素的个数 2 利用stack和set来模拟,set保存集合的元素.遇到push的时候直接在stac ...

  5. 12096 - The SetStack Computer UVA

    Background from Wikipedia: \Set theory is a branch of mathematics created principally by the German ...

  6. EOJ 1641/UVa The SetStack Computer

    Background from Wikipedia: “Set theory is a branch of mathematics created principally by the German ...

  7. UVa12096.The SetStack Computer

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  8. 集合栈计算机(The SetStack Computer, ACM/ICPC NWERC 2006,Uva12096)

    集合栈计算机(The SetStack Computer, ACM/ICPC NWERC 2006,Uva12096) 题目描述 有一个专门为了集合运算而设计的"集合栈"计算机.该 ...

  9. UVA12096 - The SetStack Computer(set + map映射)

    UVA12096 - The SetStack Computer(set + map映射) 题目链接 题目大意:有五个动作: push : 把一个空集合{}放到栈顶. dup : 把栈顶的集合取出来, ...

  10. uva 12096 - The SetStack Computer(集合栈)

    例题5-5 集合栈计算机(The Set Stack Computer,ACM/ICPC NWERC 2006,UVa12096) 有一个专门为了集合运算而设计的"集合栈"计算机. ...

随机推荐

  1. 在Ubuntu机器上使用war包安装Jenkins

    因为一些需求需要迁移之前使用的Jenkins,原来是按照官方文档使用apt方式安装的,这次搬迁后的机器由于默认不通外网(可以通过代理走外网),因此趁此机会,尝试改用war包方式安装 环境目标 系统Ub ...

  2. 【源码系列#02】Vue3响应式原理(Effect)

    专栏分享:vue2源码专栏,vue3源码专栏,vue router源码专栏,玩具项目专栏,硬核推荐 欢迎各位ITer关注点赞收藏 Vue3中响应数据核心是 reactive , reactive 的实 ...

  3. 【javaweb】integer是什么意思?integer和int的区别

    1.数据类型不同:int是基础数据类型,而integer是包装数据类型 2.默认值不同:int的默认值是0,而integer的默认值是null 3.内存中存储的方式不同:int 在内存中直接存储的是数 ...

  4. crm系统功能有哪些?

    CRM系统是指客户关系管理系统,其核心理念是将客户视为企业的宝贵资源,为了最大化地发掘和利用客户价值,运用各种先进的技术与方法来促进商业活动中所有涉及到客户的流程和业务,所以实际上CRM系统也是一个综 ...

  5. 简易的git命令行入门教程

    一.Git 全局设置 git config --global user.name "用户名" git config --global user.email "邮件地址@1 ...

  6. MySQL笔记01: MySQL入门_1.3 MySQL启动停止与登录

    1.3 MySQL启动停止与登录 1.3.1 MySQL启动与停止 MySQL数据库分为客户端和服务器端,只有服务器端服务开启以后,才可以通过客户端登录MySQL服务端. 首先,以管理员身份运行&qu ...

  7. 数据仓库主流开发语言——SQL

    数仓开发语言概述  SQL语言介绍 数仓与SQL 结构化数据 二维表结构 SQL语法分类

  8. HDU-2159 二维背包

    最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务.久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最后一级.现在的问题是,xhd升掉最后一级还需n的经 ...

  9. ElasticSearch Groovy 沙盒绕过 && 代码执行漏洞

    漏洞编号:CVE-2015-1427 漏洞详情 CVE编号 CVE-2015-1427 漏洞级别 高危7.5 标题 Elasticsearch Groovy 脚本引擎存在远程代码执行漏洞 披露时间 2 ...

  10. AI量化策略会:可以直接上实盘的策略构建方法

    一年一度的培训虽晚但到,这是BigQuant与大家走过的第五个培训年头,在过去的四年里看到很多学员的成长和蜕变,从一开始的懵懂无知,到现在对深度学习的信手拈来,BigQuant与各位学员们一样都收获颇 ...