解いた問題

9/29/2012

LiveArchive5848

分割統治。

領域を縦と横に2分割して、4つの領域に分ける。
縦は2種類の点を分ける様なX軸に垂直な直線で分割し、横はそれっぽい直線で分割する。

横方向に隣合う領域同士の近い点か、斜めの領域同士の点から最近点を探す。
互いに斜めな領域同士の点の移動は、分割に使った縦と横の線の交点を通る様な移動を考える。

あとは、点の数が少なくなるまで横の分割を繰り返す。



  1. #include <algorithm>  
  2. #include <complex>  
  3. #include <deque>  
  4. #include <functional>  
  5. #include <iomanip>  
  6. #include <iostream>  
  7. #include <map>  
  8. #include <numeric>  
  9. #include <queue>  
  10. #include <set>  
  11. #include <sstream>  
  12. #include <stack>  
  13. #include <string>  
  14. #include <utility>  
  15. #include <vector>  
  16.   
  17. #include <cassert>  
  18. #include <climits>  
  19. #include <cmath>  
  20. #include <cstdio>  
  21. #include <cstdlib>  
  22. #include <cstring>  
  23.   
  24. #define REP(i, n) for(int i=0; i<(int)n; ++i)  
  25. #define FOR(i, c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)  
  26. #define ALL(c) (c).begin(),(c).end()  
  27. #define each(i, c) FOR(i, c)  
  28.   
  29. #define unless(cond) if (!(cond))  
  30.   
  31. using namespace std;  
  32.   
  33. typedef long long int lli;  
  34. typedef unsigned long long ull;  
  35. typedef complex<double> point;  
  36.   
  37. namespace std {  
  38.   inline  
  39.   bool operator < (const point& a, const point& b)  
  40.   {  
  41.     return a.imag () < b.imag();  
  42.   }  
  43. };  
  44.   
  45. const int N = 100000 + 1;  
  46. point A[N], B[N];  
  47.   
  48. const int inf = 1 << 28;  
  49.   
  50. inline  
  51. int m_dist(const point& a, const point& b)  
  52. {  
  53.   return abs(a.real() - b.real()) + abs(a.imag() - b.imag());  
  54. }  
  55.   
  56. int conque(int begin_a, int end_a, int begin_b, int end_b, point P, int z)  
  57. {  
  58.   int v = inf;  
  59.   int u = inf;  
  60.   for (int i = begin_a; i < end_a; ++i) {  
  61.     v = min(v, m_dist(A[i], P));  
  62.   }  
  63.   for (int i = begin_b; i < end_b; ++i) {  
  64.     u = min(u, m_dist(B[i], P));  
  65.   }  
  66.   return v + u;  
  67. }  
  68.   
  69. int X;  
  70. // [begin_x, end_x)  
  71. int divide(int begin_a, int end_a, int begin_b, int end_b)  
  72. {  
  73.   if (end_a - begin_a < 5 || end_b - begin_b < 5) {  
  74.     int ret = inf;  
  75.     for (int i = begin_a; i < end_a; ++i) {  
  76.       for (int j = begin_b; j < end_b; ++j) {  
  77.         ret = min(ret, m_dist(A[i], B[j]));  
  78.       }  
  79.     }  
  80.     return ret;  
  81.   }  
  82.   
  83.   int min_I = min(A[begin_a].imag(), B[begin_b].imag());  
  84.   int max_I = min(A[end_a - 1].imag(), B[end_b - 1].imag());  
  85.   
  86.   int Y = (double)rand() * (double)(max_I - min_I) / (double)(RAND_MAX) + min_I;  
  87.   point P(X, Y);  
  88.   
  89.   int mid_a = lower_bound(A + begin_a, A + end_a, P) - A;  
  90.   int mid_b = lower_bound(B + begin_b, B + end_b, P) - B;  
  91.   
  92.   int x = divide(begin_a, mid_a, begin_b, mid_b);  
  93.   int y = divide(mid_a, end_a, mid_b, end_b);  
  94.   int z = min(x, y);  
  95.   z = min(z, conque(begin_a, mid_a, mid_b, end_b, P, z));  
  96.   z = min(z, conque(mid_a, end_a, begin_b, mid_b, P, z));  
  97.   return z;  
  98. }  
  99.   
  100. int main(int argc, char *argv[])  
  101. {  
  102.   int tc;  
  103.   cin >> tc;  
  104.   while (tc--) {  
  105.     int n;  
  106.     cin >> n;  
  107.     for (int i = 0; i < n; ++i) {  
  108.       cin >> A[i].real() >> A[i].imag();  
  109.     }  
  110.     int m;  
  111.     cin >> m;  
  112.     for (int i = 0; i < m; ++i) {  
  113.       cin >> B[i].real() >> B[i].imag();  
  114.     }  
  115.     int mx = -1;  
  116.     for (int i = 0; i < n; ++i) {  
  117.       mx = max(mx, (int)A[i].real());  
  118.     }  
  119.     int mn = inf;  
  120.     for (int i = 0; i < m; ++i) {  
  121.       mn = min(mn, (int)B[i].real());  
  122.     }  
  123.     X = abs(mx - mn) / 2;  
  124.     sort(A, A + n);  
  125.     sort(B, B + m);  
  126.     cout << divide(0, n, 0, m) << endl;  
  127.   }  
  128.   return 0;  
  129. }