AOJ 1012 Operations with Finite Sets
出典
Aizu Programming Contest, University of Aizu, Aizu-Wakamatsu, 7-8 June, 2003
問題概要
各要素が-100以上100以下の整数の集合(最大五つ)と、それを含む集合演算の式が与えられる。集合演算の結果を要素をスペースで区切って出力せよ。
演算結果が空集合の場合は"NULL"と出力せよ。
解法
構文解析+集合演算。集合演算はSTLの演算を使うと楽(ソース参照)
以下ソース
vi S[6]; string expr; vi calc(vi a,vi b,char op) { vi ret(a.size()+b.size()); vi::iterator it; switch(op) { case 'u': it=set_union(all(a),all(b),ret.begin()); break; case 'i': it=set_intersection(all(a),all(b),ret.begin()); break; case 'd': it=set_difference(all(a),all(b),ret.begin()); break; case 's': it=set_symmetric_difference(all(a),all(b),ret.begin()); break; } ret.erase(it,ret.end()); return ret; } vi eval(int s,int t) { int d=0,p=t-1; char c; for(;p>s;p--) { c=expr[p]; if(c=='(')d++; if(c==')')d--; if(d==0&&(c=='u'||c=='i'||c=='d'||c=='s'))break; } if(p==s) { if(expr[s]=='(')return eval(s+1,t-1); if(expr[s]=='c')return calc(S[5],eval(s+1,t),'d'); return S[expr[s]-'A']; } return calc(eval(s,p),eval(p+1,t),c); } int main() { char c; int n; while(cin>>c>>n) { rep(i,6)S[i].clear(); do { rep(i,n) { int t; cin>>t; S[c-'A'].pb(t); S[5].pb(t); } }while(cin>>c>>n,c!='R'); rep(i,6) sort(all(S[i])),S[i].erase(unique(all(S[i])),S[i].end()); cin>>expr; vi ans=eval(0,expr.size()); if(ans.empty())cout<<"NULL"<<endl; else rp(i,ans)cout<<ans[i]<<(i==ans.size()-1?"\n":" "); } return 0; }