解题报告——例题5-5 集合栈计算机 UVa12096
五個(gè)操作:
1、PUSH:空集{}入棧
2、DUP:當(dāng)前棧頂元素復(fù)制一份在入棧
3、UNION:出棧兩個(gè)集合,然后把二者的并集入棧
4、INTERSECT:出棧兩個(gè)元素,然后把二者的交集入棧
5、ADD:出棧兩個(gè)集合,把先出棧的集合加入到后出棧的集合中,結(jié)果入棧
心路歷程:
這道題當(dāng)真卡了我好久好久,因?yàn)樯婕暗搅?個(gè)容器的搭配使用,最開(kāi)始總是搞不懂其中的邏輯,一度想要放棄,后來(lái)我仔細(xì)思考了一下:這道題之所以卡住我不是因?yàn)橛形也粫?huì)的知識(shí)點(diǎn),純粹是因?yàn)槲覜](méi)搞懂思路,而這個(gè)問(wèn)題是可以通過(guò)不斷的思考和嘗試解決掉的,于是不斷的思考,試錯(cuò),終于把思路一點(diǎn)一點(diǎn)捋出來(lái)了。
注意點(diǎn):
1、集合中無(wú)重復(fù)值
2、count+交集+并集+差集函數(shù)的使用方法→懶癌的福音——algorithm頭文件函數(shù)全集
思路:
本題的操作時(shí)集合的集合,
stack中存放集合的集合的唯一編號(hào),map的key值是set型的,value值是int型的,key值代表每個(gè)集合的集合的編號(hào),value值代表這個(gè)集合的集合。
通過(guò)map將編號(hào)轉(zhuǎn)化為集合的集合, 壓入vector。 最后輸出vector[i].size(),就是集合的集合中集合的個(gè)數(shù) 。
如:v[s.top()].size()中:s.top()表示棧頂集合的集合的編號(hào), v[s.top()]表示棧頂集合的集合的編號(hào) 對(duì)應(yīng)的集合的集合。v[s.top()].size()表示棧頂集合的集合的
編號(hào) 對(duì)應(yīng)的集合的集合 中集合的個(gè)數(shù)。 有點(diǎn)繞是吧,繞過(guò)這個(gè)彎就好了。
舉個(gè)栗子:
輸入:
1
5
PUSH
PUSH
ADD
PUSH
INTERSECT
第一步:PUSH:
直接壓入一個(gè)空集合, 空集合的表示形式是: set()(也就是程序中的Set()),通過(guò)調(diào)用ID函數(shù)知道:這個(gè)集合在vector中不存在,就將集合入vector,再用ID函數(shù)轉(zhuǎn)化成對(duì)應(yīng)的int編號(hào)0存入stack。
輸出:此時(shí)棧頂為0,調(diào)用vector[0].size()可得棧頂集合中元素(集合)的個(gè)數(shù)為0
第二步:PUSH:
同理,壓入一個(gè)空集合,通過(guò)調(diào)用ID函數(shù)發(fā)現(xiàn)這個(gè)集合的編號(hào)(0)已經(jīng)存在,所以不需要再次壓入vector,直接將編號(hào)0存入stack(二者編號(hào)相同,也就是說(shuō)用相同的編號(hào),調(diào)用vector中的同一個(gè)值就可以,因?yàn)槎叩募鲜窍嗤?#xff0c;)
輸出:此時(shí)棧頂為0,調(diào)用vector[0].size()可得棧頂集合中元素(集合)的個(gè)數(shù)為0
第三步:ADD:
取出前兩個(gè)被壓入的空集合,將集合a放入集合b, (若二者都是空集合,相加就相當(dāng)于集合b中有一個(gè)空集合(元素),那么集合b就不是空集合了,它的長(zhǎng)度就變成了1,其他長(zhǎng)度同理)。通過(guò)調(diào)用ID函數(shù)發(fā)現(xiàn)這個(gè)全新的集合不存在,則它獲得一個(gè)新的編號(hào),這個(gè)編號(hào)存入stack。對(duì)應(yīng)編號(hào)的集合b存入vector。
輸出:此時(shí)棧頂為1,調(diào)用vector[1].size()可得棧頂集合中元素(集合)的個(gè)數(shù)為1
第四步:PUSH:
壓入一個(gè)空集合,通過(guò)調(diào)用ID函數(shù)知道,這個(gè)集合在vector中已經(jīng)出現(xiàn),編號(hào)為0,因此直接將編號(hào)0存入stack。
輸出:此時(shí)棧頂為0,調(diào)用vector[0].size()可得棧頂集合中元素(集合)的個(gè)數(shù)為0
第五步:INTERSECT
彈出stack中前兩個(gè)值,也就是前兩個(gè)編號(hào),分別是0和1,去vector中找到v[0]和v[1],用algorithm內(nèi)置函數(shù)set_intersection求出二者交集,得到一個(gè)空集合。通過(guò)調(diào)用ID函數(shù)發(fā)現(xiàn)這個(gè)“新集合”在vector中已經(jīng)出現(xiàn),編號(hào)為0,因此直接將編號(hào)0存入stack
輸出:此時(shí)棧頂為0,調(diào)用vector[0].size()可得棧頂集合中元素(集合)的個(gè)數(shù)為0
代碼:
#include<bits/stdc++.h> using namespace std;#define ALL(x) x.begin(), x.end() #define INS(x) inserter(x, x.begin())typedef set<int> Set; //方便寫(xiě)法 map<Set,int> IDcache; //把集合映射成ID vector<Set> Setcache; //存放集合 //查找給定集合X的ID,若找不到,則分配一個(gè)新ID //也就是:返回一個(gè)集合唯一的ID int ID(Set x) {if(IDcache.count(x)) return IDcache[x]; //通過(guò)key查找,找到了返回value Setcache.push_back(x); //若沒(méi)找到,則說(shuō)明是新集合,壓入vector return IDcache[x] = Setcache.size() - 1; //若沒(méi)找到,則返回一個(gè)全新的編號(hào) } int main() {int m; cin >> m;while(m--) {stack<int> s; //棧,存放每個(gè)集合的集合對(duì)應(yīng)的編號(hào) int n; cin >> n;for(int i = 0; i < n; i++) {string op; cin >> op;if(op[0] == 'P') s.push(ID(Set())); //空集合的編號(hào) else if(op[0] == 'D') s.push(s.top());else { //復(fù)用,其余操作都是有關(guān)棧頂元素及其下一個(gè)元素 Set x1 = Setcache[s.top()]; s.pop();Set x2 = Setcache[s.top()]; s.pop();Set x; //用于計(jì)算結(jié)果 ,也是存放編號(hào) if(op[0] == 'U') set_union(ALL(x1), ALL(x2), INS(x));if(op[0] == 'I') set_intersection(ALL(x1), ALL(x2), INS(x));if(op[0] == 'A') {x = x2;x.insert(ID(x1)); //生成相加后的集合的集合的編號(hào), } s.push(ID(x)); //將編號(hào)入s } cout << Setcache[s.top()].size() << endl;} } return 0 ; }收獲:
1、集合中無(wú)重復(fù)值
1、宏定義取代復(fù)雜操作
2、程序復(fù)用
3、以map做橋梁+容器嵌套,實(shí)現(xiàn)四個(gè)容器的配合使用 (哭了)
日拱一卒,功不唐捐。
總結(jié)
以上是生活随笔為你收集整理的解题报告——例题5-5 集合栈计算机 UVa12096的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 解题报告——蓝桥杯 试题 基础练习 字符
- 下一篇: 解题报告——例题 5-6团体队列(Tea