《算法竞赛入门经典2ndEdition 》例题5-5 集合栈计算机(The SetStack Computer, Uva12096)

来源:互联网 发布:一建做题软件电脑版 编辑:程序博客网 时间:2024/05/24 05:43

这道题一开始,根本就没有理解题意,看了半天Sample,一直傻傻地觉得Sample是错的,后来才意识到集合中相同的元素只能有一个,所以第五行是1,而不是2。于是理解了题意之后,瞬间思路被打开了,加上这是在STL这一章节,自然想到用STL。(不过还是看了眼程序才有了思路的)

热烈庆祝连续3道一次AC
这里写图片描述

下面是我的代码。

#include <cstdio>#include <cstring>#include <vector>#include <algorithm>#include <iostream>#include <set>#include <vector>#include <stack>#include <map>using namespace std;typedef set<int> Set;map<int, Set> ID;stack<int> st;int cnt;int getID(Set);int main(){  freopen("New Text Document.txt","r",stdin);  freopen("Output.txt","w",stdout);  ios::sync_with_stdio(false);  int t, n;  string s;  cin>>t;  cin.get();  while(t--)  {    cnt = 0;    while(!st.empty()) st.pop();    //ID.clear();    cin>>n;    while(n--)    {      cin>>s;      //cout<<s<<endl;      if(s[0] == 'P') st.push(getID(Set()));      else if(s[0] == 'D') st.push(st.top());      else      {        Set s1 = ID[st.top()]; st.pop();        Set s2 = ID[st.top()]; st.pop();        Set s3;        s3.clear();        if(s[0] == 'U')         {          set_union(s1.begin(), s1.end(), s2.begin(), s2.end(), insert_iterator<Set>(s3, s3.begin()));          st.push(getID(s3));        }        if(s[0] == 'I')        {          set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), insert_iterator<Set>(s3, s3.begin()));          st.push(getID(s3));        }        if(s[0] == 'A')        {          s2.insert(getID(s1));          st.push(getID(s2));        }      }      Set s = ID[st.top()];      cout<<s.size()<<endl;    }     //cout<<cnt;    //while(!st.empty())//    {//      cout<<ID[st.top()].size()<<endl;//      st.pop();//    }    //for(int i = 1; i <= cnt; i++)      //cout<<ID[i].size();    cout<<"***"<<endl;  }  return 0;} int getID(Set s){  for(int i = 1; i <= cnt; i++)  if(ID[i] == s) return i;   ID[++cnt] = s;//之前一直没写这个导致出错,没有将新集合加入到映射数组ID中   return cnt;}

下面是刘汝佳标程。标程用的是Set到int的映射,我的程序用的是int到Set的映射。

// UVa12096 The SetStack Computer// Rujia Liu#include<iostream>#include<string>#include<set>#include<map>#include<stack>#include<vector>#include<algorithm>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; // 把集合映射成IDvector<Set> Setcache; // 根据ID取集合// 查找给定集合x的ID。如果找不到,分配一个新IDint ID (Set x) {  if (IDcache.count(x)) return IDcache[x];  Setcache.push_back(x); // 添加新集合  return IDcache[x] = Setcache.size() - 1;}int main () {  int T;  cin >> T;  while(T--) {    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));      }            cout << Setcache[s.top()].size() << endl;    }    cout << "***" << endl;  }  return 0;  }
2 0