Problem 1031 : Simple GUI Application
Problem C: Simple GUI Application
http://rose.u-aizu.ac.jp/onlinejudge/ProblemSet/description.jsp?id=1031
- 問題概要
パネルが階層的に配置されてる。
上の階層のパネルはその下の階層のパネルに内包されている。
同じ階層にいるパネルは重ならない。
パネルの左上右上の座標が与えられる。
n個の座標が与えられる。
その座標にあるパネルで1番上の階層のパネルの名前と、そのパネルに直接のっているパネルの枚数を答えよ。
- 解法
構文解析?
パーザー書かないとダメかなーと思ってたけど、
記号を空白文字に置き換えて、string stream で読み込んで、スタックで今どのパネルの上か記憶して、
直接のっているパネルの枚数を数えた。
- ソース
#include<iostream> #include<string> #include<algorithm> #include<vector> #include<map> #include<set> #include<cstdlib> #include<cstdio> #include<cmath> #include<sstream> #include<cassert> #include<queue> #include<stack> #define REP(i,b,n) for(int i=b;i<n;i++) #define rep(i,n) REP(i,0,n) #define ALL(C) (C).begin(),(C).end() #define pb push_back #define mp make_pair #define vint vector<int> #define FOR(it,o) for(__typeof((o).begin()) it=(o).begin(); it!=(o).end(); ++it) #define lli long long int #define ld long double using namespace std; class GUI{ public: int x1, y1, x2, y2; int rank, cnt; string s; GUI(){ cnt = 0; } bool operator < (const GUI g) const { return rank > g.rank; } bool on(int x, int y){ if(s == "OUT OF MAIN PANEL")return true; return ( x >= x1 && y >= y1 && x <= x2 && y <= y2); } }; main(){ int n; while(cin >> n){ string s; cin >> s; rep(i, s.length()){ if(s[i] == '<' || s[i] == '>' || s[i] == ',' || s[i] == '/')s[i] = ' '; } stringstream sin(s); vector<GUI> G; map<string, int> index; set<string> used; int cnt = 0; stack<string> p; p.push("OUT OF MAIN PANEL"); GUI base; base.s = "OUT OF MAIN PANEL"; base.rank = -1; G.push_back(base); while(sin >> s){ if(used.find(s) != used.end()){ cnt--; p.pop(); continue; } used.insert(s); G[index[p.top()]].cnt++; p.push(s); GUI g; g.rank = cnt; cnt++; g.s = s; sin >> g.x1 >> g.y1 >> g.x2 >> g.y2; index[s] = G.size(); G.push_back(g); } sort(ALL(G)); rep(i, n){ int x, y; cin >> x >> y; FOR(it, G){ if((*it).on(x, y)){ cout << (*it).s << ' ' << (*it).cnt <<endl; break; } } } } }