Source code for submission s695

fo.cpp

  1. #include <algorithm>
  2. #include <cctype>
  3. #include <cmath>
  4. #include <complex>
  5. #include <cstdio>
  6. #include <cstring>
  7. #include <iomanip>
  8. #include <iostream>
  9. #include <list>
  10. #include <map>
  11. #include <queue>
  12. #include <set>
  13. #include <sstream>
  14. #include <stack>
  15. #include <string>
  16. #include <utility>
  17.  
  18. using namespace std;
  19.  
  20. #define DEBUG(x) cout << ">>> " << #x << " : " << x << endl;
  21. #define REP(i,a) for (int i = 0; i < (a); ++i)
  22. #define FOR(i,a,b) for (int i = (a); i <= (b); ++i)
  23. #define FORD(i,a,b) for (int i = (a); i >= (b); --i)
  24. inline bool EQ(double a, double b) { return fabs(a-b) < 1e-9; }
  25. const int INF = 1<<29;
  26.  
  27. typedef long long ll;
  28.  
  29.  
  30. struct Vector {
  31. Vector(double x_, double y_): x(x_), y(y_) {}
  32. double x, y;
  33. bool operator < (const Vector& o) const {
  34. if (x != o.x) return x < o.x;
  35. return y < o.y;
  36. }
  37. Vector operator - (const Vector& o) const {
  38. return Vector(x-o.x, y-o.y);
  39. }
  40. double size() const {
  41. return sqrt(x*x+y*y);
  42. }
  43. };
  44.  
  45. double cross_product(Vector v1, Vector v2) {
  46. return v1.x*v2.y - v1.y*v2.x;
  47. }
  48.  
  49. double direction(Vector segment1, Vector segment2, Vector point) {
  50. return cross_product(point-segment1, segment2-segment1);
  51. }
  52.  
  53. void convex_hull(vector<Vector>& points, vector<Vector>& hull) {
  54. sort(points.begin(), points.end());
  55. vector<Vector> top, bot;
  56. REP(i, (int)points.size()) {
  57. while (top.size() >= 2 && direction(top[top.size()-2], points[i], top[top.size()-1]) <= 0) {
  58. top.pop_back();
  59. }
  60. top.push_back(points[i]);
  61. while (bot.size() >= 2 && direction(bot[bot.size()-2], points[i], bot[bot.size()-1]) >= 0) {
  62. bot.pop_back();
  63. }
  64. bot.push_back(points[i]);
  65. }
  66. reverse(bot.begin(), bot.end());
  67. hull = top;
  68. if (bot.size() > 2) {
  69. hull.insert(hull.end(), bot.begin()+1, bot.end()-1);
  70. }
  71. }
  72.  
  73. int N;
  74. vector<Vector> points;
  75. vector<Vector> hull;
  76.  
  77. bool canImprove(int last, Vector base, Vector dir) {
  78. double score = cross_product(hull[last]-base, dir);
  79. int next = last+1;
  80. if (next == (int)hull.size()) next = 0;
  81. double opt = cross_product(hull[next]-base, dir);
  82. return opt > score;
  83. }
  84.  
  85. int main() {
  86. while (scanf("%d", &N) == 1) {
  87. double best = 1.0/0.0;
  88. points.clear();
  89. hull.clear();
  90. int x, y;
  91. REP(i,N) {
  92. scanf("%d%d", &x, &y);
  93. points.push_back(Vector(x, y));
  94. }
  95. convex_hull(points, hull);
  96. int lastLeft = 0, lastTop = 0, lastRight = 0;
  97. double leftScore = 0, topScore = 0, rightScore = 0;
  98. Vector baseVec = hull[1] - hull[0];
  99. Vector perpVec(baseVec.y, -baseVec.x);
  100. REP(i, (int)hull.size()) {
  101. double opt = cross_product(hull[i]-hull[0], baseVec);
  102. if (opt < topScore) {
  103. lastTop = i;
  104. topScore = opt;
  105. }
  106. opt = cross_product(hull[i]-hull[0], perpVec);
  107. if (opt > leftScore) {
  108. lastLeft = i;
  109. leftScore = opt;
  110. }
  111. if (opt < rightScore) {
  112. lastRight = i;
  113. rightScore = opt;
  114. }
  115. }
  116. REP(base1, (int)hull.size()) {
  117. int base2 = base1+1;
  118. if (base2 == (int)hull.size()) base2 = 0;
  119. Vector baseVec = hull[base2] - hull[base1];
  120. Vector perpVec(baseVec.y, -baseVec.x);
  121. while (canImprove(lastTop, hull[base1], Vector(0,0) - baseVec)) {
  122. ++lastTop;
  123. if (lastTop == (int)hull.size()) lastTop = 0;
  124. }
  125. while (canImprove(lastLeft, hull[base1], perpVec)) {
  126. ++lastLeft;
  127. if (lastLeft == (int)hull.size()) lastLeft = 0;
  128. }
  129. while (canImprove(lastRight, hull[base1], Vector(0,0)-perpVec)) {
  130. ++lastRight;
  131. if (lastRight == (int)hull.size()) lastRight = 0;
  132. }
  133. topScore = cross_product(hull[lastTop]-hull[base1], baseVec);
  134. leftScore = cross_product(hull[lastLeft]-hull[base1], perpVec);
  135. rightScore = cross_product(hull[lastRight]-hull[base1], perpVec);
  136. double baseSize = baseVec.size();
  137. topScore /= baseSize; leftScore /= baseSize; rightScore /= baseSize;
  138. //DEBUG(leftScore);
  139. //DEBUG(rightScore);
  140. //DEBUG(topScore);
  141. double total = 2*(leftScore - rightScore) - 2*topScore;
  142. if (total < best) best = total;
  143. //DEBUG(total);
  144. }
  145. printf("%lf\n", best);
  146. }
  147. return 0;
  148. }
  149.