题目大意

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

  • 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. 提升效率,打通万里牛ERP与下游用友U8财务软件的无缝对接

    一.对接流程 1.1 销售/售后流程 在万里牛订单出库后,通过轻易云数据集成平台将数据推送至用友U8销售订单和销售出库单,这些单据可以进行关联操作. 当万里牛售后单完成退货入库后,通过数据集成平台将数 ...

  2. 3C智能移动周边产品龙头企业如何集成企业内部所有异构系统数据

    全面并自动集成品胜集团全域业务系统中的各类业务数据:结构化.标准化.自动化集团全部异构系统数据,提升全公司整体项目管理水平:梳理与简化跨部门.跨系统流程,清晰定义流程节点及业务边界,打通部门间信息流通 ...

  3. 汇报工作与众不同:在PPT中展示Datainside动态图表

    题目要求了解在PPT中展示Datainside动态图表,下面是关于该主题的详细介绍. 内容可视化:概念与定义 内容可视化(Data Visualization)是将数据以图形或其他视觉形式呈现的过程, ...

  4. [JDK/APM] 应用诊断工具之VisualVM

    1 概述 1.1 简介 VisualVM is a visual tool integrating commandline JDK tools and lightweight profiling ca ...

  5. 吉特日化MES系统&生产工艺控制参数对照表

    吉特日化MES生产工艺参数对照表 工艺编号 PROCE_BASE_TIMER 工艺名称 定时器 工艺说明 主要用于生产工艺步骤过程计时 参数编号 参数名称 参数描述 Prop_Timer_Enable ...

  6. bash shell笔记整理——basename和dirname命令

    bashname命令作用 去掉给定name的目录部分,如果指定了 SUFFIX, 就 同时去掉SUFFIX(后缀).具体看示例吧. bashname语法 Usage: basename NAME [S ...

  7. 华企盾DSC防泄密客户端安装卡住

    解决方法: 1.安装了杀毒或者同行软件,退出后安装不行的话卸载掉 2.注册表编辑被管理员禁用,导致客户端安装时一直卡住,启用注册表编辑(后续2021.6.21后发布的版本可直接安装) 由于安装了卡巴斯 ...

  8. 使用.NET Core接入飞书AI

    飞书AI接入教程 首先,准备俩个账号:ChatGPT账号.飞书账号. 飞书账号请自行注册,访问链接 www.feishu.cn/ 即可登录. 第一步,飞书进入开发者平台.点击创建应用. 填写应用名称和 ...

  9. 快速上手 dbt 数据转换工具 -- dbt core 命令进阶篇

    引 根据第一篇文章的约定,我想通过接下来的几篇文章带大家进一步了解 dbt 的用法,原计划这篇文章我会介绍 dbt 命令的进阶用法,进一步认识 dbt 的配置以及如何创建增量表等等零零散散十几个方面的 ...

  10. Redis配置模式及各自优缺点

    大家好,我是闲者,今天简单聊下redis部署模式.Redis支持多种不同的数据结构和模式,以满足不同的使用场景.以下是一些常见的Redis配置和模式示例以及详解.原文地址:Redis配置模式及各自优缺 ...