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