1. 程式人生 > >UVA 12096 The SetStack Computer

UVA 12096 The SetStack Computer

題意
有一個專門為了集合運算而設計的“集合棧”計算機。該機器有一個開始為空的棧並且支援以下操作。
1.PUSH:空集“{}”入棧。
2.DUP:把當前棧頂元素複製一份後在入棧。
3.UNION:出棧兩個集合,然後把二者的並集入棧。
4.INTERSECT:出棧兩個集合,然後把二者的交集入棧。
5.ADD:出棧兩個集合,然後把先出棧的集合加入到後出棧的集合中,把結果入棧。

例如,棧頂元素是A = { {},{{}} },下一個元素是B = { {}, {{{}}} },則:
UNION 操作將得到{ {}, {{}}, {{{}}} },輸出3.
INTERSECT 操作將得到{ {} },輸出1。
ADD 操作將得到{ {}, {{{}}},{{} , {{}}} },輸出3。
輸入
第一行有一個整數T(0<=T<=5)表示有T組測試資料。
每組測試資料有N(0<=N<=2000)次操作,保證操作均能順利進行(不需要對空棧執行出棧操作)。
輸出
對於輸入中指定的每個操作,輸出棧頂集合的大小(即元素個數)並換行。
每組測試資料後輸出一行“***”。
樣例輸入
2
9
PUSH
DUP
ADD
PUSH
ADD
DUP
ADD
DUP
UNION
5
PUSH
PUSH
ADD
PUSH
INTERSECT
樣例輸出
0
0
1
0
1
1
2
2
2
***
0
0
1
0
0
***
不得不說再一次見識到了STL容器的強大,竟然還有這種函式,這次真正的跪下來膜拜了,唉,以後估計用不多,就記在小本本上了,感謝劉汝佳,感謝紫書!
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
typedef set<int> Set;
map<Set, int> IDcache;//把集合對映成ID
vector<Set> Setcache; //根據ID取集合

//查詢給定集合x的ID。如果找不到,分配一個新的ID
int ID(Set x) {
	if(IDcache.count(x)) return IDcache[x];
	Setcache.push_back(x);  //新增新集合 
	return IDcache[x] = Setcache.size() - 1;
} 
//定義兩個巨集 
#define ALL(x) x.begin(), x.end()
#define INS(x) inserter(x, x.begin())

int main() {
	stack<int> s;
	int n, N;
	cin >> N;
	while(N--) {
		cin >> n;
		string op;
		for(int i = 0; i < n; i++) {
			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;
				//set_unition(並集),set_intersection(交集),set_difference(差集)
				
				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));
			}
			cout << Setcache[s.top()].size() << endl;
		}
		cout << "***" << endl;
	}
	return 0;
}