Codeforces 89 B. Widget Library
問題
Widgetを作るライブラリがあり、次のような命令をもつ。
- Widget name(x,y) 名前がnameで幅x高さyのWidgetを作る
- Hbox name 名前がnameのHboxを作る
- Vbox name 名前がnameのVboxを作る
- name1.pack(name2) 名前がname1のウィジェットの中にname2のウィジェットを入れる
- name.set_border(x) 名前がnameのウィジェットのボーダーをセットする
- name.set_spacing(x) 名前がnameのウィジェットのスペースをセットする
Hbox,Vboxは、内部にウィジェットを複数持つことができるウィジェットで、
Hboxは横に、Vboxは縦に要素が、spacingの間隔をあけて並ぶ。
spacingとは別に、borderの幅だけ、ウィジェットの幅は大きくなる。
(詳細は本文中の図を参照)
内部に何もWidgetをもたないHbox,Vboxは、border,spacingの値にかかわらず、
幅、高さがともに0になるものとする。
Widgetを作る命令列が与えられたとき、各ウィジェットの幅および高さを出力せよ。
出力はWidgetの名前が昇順になるようにせよ。
制約条件
命令の数≦100
方針
がんばってparseして、最後に幅と高さをDFSして計算する。
計算した幅と高さはメモ化しておく。
ソースコード
struct S{ string type,name; ll w,h,b,s; vi cld; }; S widget[101]; int n,sz; pi rec(int c){ ll &w=widget[c].w, &h=widget[c].h; if(w>=0)return mp(w,h); w=0; h=0; rep(i,widget[c].cld.size()){ pi p=rec(widget[c].cld[i]); if(widget[c].type=="H"){ h=max(h,p.second); w+=(i?widget[c].s:0)+p.first; } else{ w=max(w,p.first); h+=(i?widget[c].s:0)+p.second; } } if(widget[c].cld.size()){ w+=2*widget[c].b; h+=2*widget[c].b; } return mp(w,h); } void run() { string in; getline(cin,in); n=atoi(in.c_str()); sz=0; rep(i,n)widget[i].w=widget[i].h=-1; rep(it,n){ getline(cin,in); rep(i,in.size())if(!isalnum(in[i]))in[i]=' '; stringstream ss(in); ss>>in; if(in[0]=='W'){ ss>>widget[sz].name>>widget[sz].w>>widget[sz].h; widget[sz++].type="W"; } else if(in[0]=='V'||in[0]=='H'){ ss>>widget[sz].name; widget[sz++].type=in.substr(0,1); } else{ string method; ss>>method; if(method[0]=='s'){ ss>>method; ll x; ss>>x; rep(i,sz)if(widget[i].name==in){ if(method[0]=='b')widget[i].b=x; else widget[i].s=x; } } else{ string nm; ss>>nm; rep(i,sz)if(widget[i].name==in) rep(j,sz)if(widget[j].name==nm){ widget[i].cld.pb(j); break; } } } } vs ans; rep(i,sz){ rec(i); stringstream ss; ss<<widget[i].name<<" "<<widget[i].w<<" "<<widget[i].h; ans.pb(ss.str()); } sort(all(ans)); rep(i,ans.size())cout<<ans[i]<<endl; }