UVa12096 The SetStack Computer

        题意:集合栈计算机。。这是迄今为止我见过的最奇葩的一道题。有一个栈,栈中元素是集合,集合内部的元素还是集合。然后有5种操作,1入栈一个空集,2入栈一个和栈顶一样的集合,3出栈两个集合,入栈他们的并,4出栈两个集合,入栈他们的交,5出栈两个集合,把先出栈的集合加入后出栈的集合中,把结果入栈。每次操作后,输出栈顶集合的大小。

        思路:照着紫书上面的代码敲的。其实本来都是空集,只有操作5能最先产生非空集,也就是出现了一个这样的集合,它的元素是一个空集。。。

        再来说说那两个cache,实际上是把集合和它的ID双向映射,将不同的集合赋以不同的整数实在是精妙。。

        最后是通过这题学到了set_union()和set_intersection()两个函数。还有用到了所谓的“插入迭代器”,这个留给日后学习把。


#include <iostream>        
#include <stdio.h>        
#include <cmath>        
#include <algorithm>        
#include <iomanip>        
#include <cstdlib>        
#include <string>        
#include <memory.h>        
#include <vector>        
#include <queue>        
#include <stack>        
#include <map>      
#include <set>      
#include <ctype.h>        
#define INF 1000000010    
#define ll long long    
#define max3(a,b,c) max(a,max(b,c))    
#define MAXN 100010   

using namespace std;

typedef set<int> Set;
map<Set,int> IDcache;
vector<Set> Setcache;


int ID(Set s){
	if(IDcache.count(s))return IDcache[s];
	Setcache.push_back(s);
	return IDcache[s]=Setcache.size()-1;
}

int main(){
	int t;
	cin>>t;
	while(t--){
		stack<int> s;
		int n;
		cin>>n;
		string oper;
		for(int i=0;i<n;i++){
			cin>>oper;
			if(oper[0]=='P') s.push(ID(Set()));
			else if (oper[0]=='D') s.push(s.top());
			else{
				Set x1=Setcache[s.top()]; s.pop();
				Set x2=Setcache[s.top()]; s.pop();
				Set x;
				
				if(oper[0]=='U') set_union(x1.begin(),x1.end(),x2.begin(),x2.end(),inserter(x,x.begin()));
				if(oper[0]=='I') set_intersection(x1.begin(),x1.end(),x2.begin(),x2.end(),inserter(x,x.begin()));
				if(oper[0]=='A') {
					x=x2; x.insert(ID(x1));
				}
				s.push(ID(x));
			}
			cout<<Setcache[s.top()].size()<<endl;
		}
		cout<<"***"<<endl;
	}
	
	return 0;
}


你可能感兴趣的:(集合,uva)