POJ 1231 - The Alphabet Game
http://poj.org/problem?id=1231
概要
二次元上に k 種類のアルファベットをそれぞれ p 個書かれている. 何本か直線を引いて,同じ領域には同じアルファベットが p 個すべて含まれるように分割できるかどうかを答える.
制約
- 1 <= テストケース <= 10
- 1 <= k <= 26
- 1 <= p <= 10
- 1 <= 座標 <= 1000000
解法
同じアルファベットすべてを囲むような長方形を考えると,条件を満たすような直線はその長方形の辺に沿ったもので,他の長方形を分割しないようなものになる. そのような直線すべてで分割して,最終的に k 個の領域になっていれば YES,そうでなければ NO.
poj/1231.cc1 #include <iostream> 2 #include <vector> 3 using namespace std; 4 5 struct rect 6 { 7 int left, right, top, bottom; 8 }; 9 10 vector<vector<rect> > cut_horiz(const vector<vector<rect> >& a, int x) 11 { 12 vector<vector<rect> > b; 13 for (vector<vector<rect> >::const_iterator it(a.begin()); it != a.end(); ++it) { 14 vector<rect> l, r; 15 for (vector<rect>::const_iterator jt(it->begin()); jt != it->end(); ++jt) { 16 if (jt->left < x && x < jt->right) { 17 // contains 18 return a; 19 } else if (x <= jt->left) { 20 // kt is right 21 r.push_back(*jt); 22 } else { 23 // kt is left 24 l.push_back(*jt); 25 } 26 } 27 if (!l.empty()) { 28 b.push_back(l); 29 } 30 if (!r.empty()) { 31 b.push_back(r); 32 } 33 } 34 return b; 35 } 36 37 vector<vector<rect> > cut_vert(const vector<vector<rect> >& a, int y) 38 { 39 vector<vector<rect> > b; 40 for (vector<vector<rect> >::const_iterator it(a.begin()); it != a.end(); ++it) { 41 vector<rect> u, l; 42 for (vector<rect>::const_iterator jt(it->begin()); jt != it->end(); ++jt) { 43 if (jt->bottom < y && y < jt->top) { 44 // contains 45 return a; 46 } else if (y <= jt->bottom) { 47 // kt is upper 48 u.push_back(*jt); 49 } else { 50 // kt is lower 51 l.push_back(*jt); 52 } 53 } 54 if (!u.empty()) { 55 b.push_back(u); 56 } 57 if (!l.empty()) { 58 b.push_back(l); 59 } 60 } 61 return b; 62 } 63 64 int main() 65 { 66 int T; 67 cin >> T; 68 while (T-- > 0) { 69 int K, P; 70 cin >> K >> P; 71 vector<rect> v; 72 for (int i = 0; i < K; i++) { 73 rect r; 74 r.left = r.bottom = 100000000; 75 r.right = r.top = 0; 76 for (int j = 0; j < P; j++) { 77 int x, y; 78 cin >> x >> y; 79 r.left = min(r.left, x-1); 80 r.right = max(r.right, x); 81 r.bottom = min(r.bottom, y-1); 82 r.top = max(r.top, y); 83 } 84 v.push_back(r); 85 } 86 87 vector<vector<rect> > a(1, v); 88 for (vector<rect>::const_iterator it(v.begin()); it != v.end(); ++it) { 89 a = cut_horiz(a, it->left); 90 a = cut_horiz(a, it->right); 91 a = cut_vert(a, it->top); 92 a = cut_vert(a, it->bottom); 93 } 94 if (a.size() == K) { 95 cout << "YES" << endl; 96 } else { 97 cout << "NO" << endl; 98 } 99 } 100 return 0; 101 }