Source code for submission s900

fo.cpp

  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <cstdio>
  4. #include <vector>
  5. #include <algorithm>
  6. #include <cmath>
  7. #include <climits>
  8.  
  9. typedef unsigned int uint;
  10. typedef long double number;
  11.  
  12. struct point {
  13. number x, y;
  14.  
  15. point():
  16. x(0.0),
  17. y(0.0) {
  18. }
  19.  
  20. point(number x, number y):
  21. x(x),
  22. y(y) {
  23. }
  24. };
  25.  
  26. bool operator== (const point& a, const point& b) {
  27. return a.x == b.x && a.y == b.y;
  28. }
  29.  
  30. bool operator!= (const point& a, const point& b) {
  31. return a.x != b.x || a.y != b.y;
  32. }
  33.  
  34. bool operator< (const point& a, const point& b) {
  35. return a.x == b.x ? a.y < b.y : a.x < b.x;
  36. }
  37.  
  38. bool operator> (const point& a, const point& b) {
  39. return a.x == b.x ? a.y > b.y : a.x > b.x;
  40. }
  41.  
  42. number cross(const point& a, const point& b, const point& c) {
  43. return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
  44. }
  45.  
  46. number dist(const point& a, const point& b) {
  47. number dx = b.x - a.x;
  48. number dy = b.y - a.y;
  49. if (dx == 0.0 && dy == 0.0)
  50. return 0.0;
  51.  
  52. return sqrt( dx * dx + dy * dy );
  53. }
  54.  
  55. point center(const point& p1, const point& p2, const point& far) {
  56. if (p1.x == p2.x)
  57. return point(p1.x, far.y);
  58. if (p1.y == p2.y)
  59. return point(far.x, p1.y);
  60.  
  61. number k = (p2.y - p1.y) / (p2.x - p1.x);
  62. number kperp = (p1.x - p2.x) / (p2.y - p1.y);
  63. number d = p2.y - k * p2.x;
  64. number dperp = far.y - kperp * far.x;
  65. number xint = (d - dperp) / (kperp - k);
  66. number yint = kperp * xint + dperp;
  67. return point(xint, yint);
  68. }
  69.  
  70. void obtainconvexhull(std::vector<point>& hull, std::vector<point>& points) {
  71. std::sort(points.begin(), points.end());
  72. hull.push_back(points[0]);
  73. uint last_added = 0;
  74. uint ref;
  75.  
  76. do
  77. {
  78. ref = 0;
  79. for (uint j = 0; j < points.size(); j++)
  80. {
  81. int wedge = cross(hull[last_added], points[ref], points[j]);
  82. if (points[ref] == hull[last_added] || wedge < 0)
  83. ref = j;
  84. }
  85. if (ref != 0)
  86. {
  87. hull.push_back(points[ref]);
  88. points.erase(points.begin()+ref);
  89. last_added++;
  90. }
  91. }
  92. while (ref != 0);
  93. }
  94.  
  95. number getminwidth(std::vector<point>& polygon) {
  96. uint aux = polygon.size();
  97. number minwidthoverall = INT_MAX; // WHAT?
  98. for (uint i = 0; i < aux; i++)
  99. {
  100. number maxwidthforoneside = 0.0;
  101. point maxc;
  102. point lineA = polygon[i];
  103. point lineB = polygon[(i + 1) % aux];
  104.  
  105. for (uint j = 0; j < aux; j++)
  106. if (polygon[j] != lineA && polygon[j] != lineB)
  107. {
  108. point c = center(lineA, lineB, polygon[j]);
  109. number d = dist(c, polygon[j]);
  110. //~ if (d > 21213212)
  111. //~ printf("bad: c.x=%Lf, c.y=%Lf, pol[j].x=%Lf, pol[j].y=%Lf\n", c.x, c.y, polygon[j].x, polygon[j].y);
  112. if (maxwidthforoneside < d)
  113. {
  114. maxwidthforoneside = d;
  115. maxc = polygon[j];
  116. }
  117. }
  118.  
  119. number left = 0.0; // product < 0
  120. number right = 0.0; // product > 0
  121. point ab = center(lineA, lineB, maxc);
  122. for (uint j = 0; j < aux; j++)
  123. {
  124. if (maxc == polygon[j])
  125. continue;
  126.  
  127. point c = center(maxc, ab, polygon[j]);
  128. number d = dist(c, polygon[j]);
  129. number product = cross(maxc, ab, polygon[j]);
  130. if (product < 0)
  131. left = std::max(left, d);
  132. if (product > 0)
  133. right = std::max(right, d);
  134. }
  135.  
  136. //~ printf("current minwidth: %Lf\n", minwidthoverall);
  137. //~ printf("maxwidthforoneside: %Lf, left: %Lf, right: %Lf\n", maxwidthforoneside, left, right);
  138. minwidthoverall = std::min(minwidthoverall, maxwidthforoneside * 2 + (left + right) * 2);
  139. //~ printf("new minwidth: %Lf\n\n", minwidthoverall);
  140. }
  141. return minwidthoverall;
  142. }
  143.  
  144. int main() {
  145. int vertices;
  146.  
  147. while (true)
  148. {
  149. if (1 != scanf("%d", &vertices))
  150. break;
  151.  
  152. std::vector<point> polygon;
  153. while (vertices--)
  154. {
  155. int x, y;
  156. scanf("%d %d", &x, &y);
  157. polygon.push_back(point(number(x), number(y)));
  158. }
  159.  
  160. std::vector<point> convexhull;
  161. obtainconvexhull(convexhull, polygon);
  162. number answertoeverything = getminwidth(convexhull);
  163.  
  164. printf("%Lf\n", answertoeverything);
  165. }
  166.  
  167. return 0;
  168. }
  169.