Source code for submission s983

Go to diff to previous submission

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 halfdist(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 dx * dx + dy * dy;
  53. }
  54.  
  55. number dist(const point& a, const point& b) {
  56. return sqrt( halfdist(a, b) );
  57. }
  58.  
  59. point center(const point& p1, const point& p2, const point& far) {
  60. if (p1.x == p2.x)
  61. return point(p1.x, far.y);
  62. if (p1.y == p2.y)
  63. return point(far.x, p1.y);
  64.  
  65. number k = (p2.y - p1.y) / (p2.x - p1.x);
  66. number kperp = (p1.x - p2.x) / (p2.y - p1.y);
  67. number d = p2.y - k * p2.x;
  68. number dperp = far.y - kperp * far.x;
  69. number xint = (d - dperp) / (kperp - k);
  70. number yint = kperp * xint + dperp;
  71. return point(xint, yint);
  72. }
  73.  
  74. void obtainconvexhull(std::vector<point>& hull, std::vector<point>& points) {
  75. std::sort(points.begin(), points.end());
  76. hull.push_back(points[0]);
  77. uint last_added = 0;
  78. uint ref;
  79.  
  80. do
  81. {
  82. ref = 0;
  83. for (uint j = 0; j < points.size(); j++)
  84. {
  85. int wedge = cross(hull[last_added], points[ref], points[j]);
  86. if (points[ref] == hull[last_added] || wedge < 0)
  87. ref = j;
  88. }
  89. if (ref != 0)
  90. {
  91. hull.push_back(points[ref]);
  92. points.erase(points.begin()+ref);
  93. last_added++;
  94. }
  95. }
  96. while (ref != 0);
  97. }
  98.  
  99. number getminwidth(std::vector<point>& polygon) {
  100. uint aux = polygon.size();
  101. number minwidthoverall = INT_MAX; // WHAT?
  102. point firstmaxc;
  103. bool is_firstmaxc = false;
  104. for (uint i = 0; i < aux; i++)
  105. {
  106. number maxwidthforoneside = 0.0;
  107. point maxc;
  108.  
  109. if (is_firstmaxc && polygon[i] == firstmaxc)
  110. break;
  111.  
  112. point lineA = polygon[i];
  113. point lineB = polygon[(i + 1) % aux];
  114.  
  115. for (uint j = 0; j < aux; j++)
  116. if (polygon[j] != lineA && polygon[j] != lineB)
  117. {
  118. point c = center(lineA, lineB, polygon[j]);
  119. number d = halfdist(c, polygon[j]);
  120. //~ if (d > 21213212)
  121. //~ 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);
  122. if (maxwidthforoneside < d)
  123. {
  124. maxwidthforoneside = d;
  125. maxc = polygon[j];
  126. }
  127. }
  128. if (!is_firstmaxc)
  129. firstmaxc = maxc;
  130.  
  131. //~ number best_left_cross = 0;
  132. //~ number best_right_cross = 0;
  133. //~ point bestleft, bestright;
  134. point ab = center(lineA, lineB, maxc);
  135. //~ for (uint j = 0; j < aux; j++)
  136. //~ {
  137. //~ if (maxc == polygon[j])
  138. //~ continue;
  139. //~ number product = cross(maxc, ab, polygon[j]);
  140. //~ if (best_left_cross > product)
  141. //~ {
  142. //~ best_left_cross = product;
  143. //~ bestleft = polygon[j];
  144. //~ }
  145. //~ if (best_right_cross < product)
  146. //~ {
  147. //~ best_right_cross = product;
  148. //~ bestright = polygon[j];
  149. //~ }
  150. //~ }
  151.  
  152. number left = 0.0; // product < 0
  153. number right = 0.0; // product > 0
  154. //~ {
  155. //~ point c = center(maxc, ab, bestleft);
  156. //~ left = dist(c, bestleft);
  157. //~ }
  158. //~ {
  159. //~ point c = center(maxc, ab, bestright);
  160. //~ right = dist(c, bestright);
  161. //~ }
  162.  
  163. for (uint j = 0; j < aux; j++)
  164. {
  165. point c = center(maxc, ab, polygon[j]);
  166. number product = cross(maxc, ab, polygon[j]);
  167. number d = halfdist(c, polygon[j]);
  168. if (product < 0)
  169. left = std::max(left, d);
  170. if (product > 0)
  171. right = std::max(right, d);
  172. }
  173.  
  174. //~ printf("current minwidth: %Lf\n", minwidthoverall);
  175. //~ printf("maxwidthforoneside: %Lf, left: %Lf, right: %Lf\n", maxwidthforoneside, left, right);
  176. number candidate = sqrt(maxwidthforoneside) * 2 + (sqrt(left) + sqrt(right)) * 2;
  177. minwidthoverall = std::min(minwidthoverall, candidate);
  178. //~ printf("new minwidth: %Lf\n\n", minwidthoverall);
  179. }
  180. return minwidthoverall;
  181. }
  182.  
  183. int main() {
  184. int vertices;
  185.  
  186. while (true)
  187. {
  188. if (1 != scanf("%d", &vertices))
  189. break;
  190.  
  191. std::vector<point> polygon;
  192. while (vertices--)
  193. {
  194. int x, y;
  195. scanf("%d %d", &x, &y);
  196. polygon.push_back(point(number(x), number(y)));
  197. }
  198.  
  199. std::vector<point> convexhull;
  200. obtainconvexhull(convexhull, polygon);
  201. number answertoeverything = getminwidth(convexhull);
  202.  
  203. printf("%Lf\n", answertoeverything);
  204. }
  205.  
  206. return 0;
  207. }
  208.  

Diff to submission s907

fo.cpp

--- c5.s907.cteam063.fo.cpp.0.fo.cpp
+++ c5.s983.cteam063.fo.cpp.0.fo.cpp
@@ -44,5 +44,5 @@
 }
 
-number dist(const point& a, const point& b) {
+number halfdist(const point& a, const point& b) {
         number dx = b.x - a.x;
         number dy = b.y - a.y;
@@ -50,5 +50,9 @@
                 return 0.0;
         
-        return sqrt( dx * dx + dy * dy );
+        return dx * dx + dy * dy;
+}
+
+number dist(const point& a, const point& b) {
+        return sqrt( halfdist(a, b) );
 }
 
@@ -113,5 +117,5 @@
                         {
                                 point c = center(lineA, lineB, polygon[j]);
-                                number d = dist(c, polygon[j]);
+                                number d = halfdist(c, polygon[j]);
                                 //~ if (d > 21213212)
                                         //~ 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);
@@ -125,15 +129,41 @@
                         firstmaxc = maxc;
                 
+                //~ number best_left_cross = 0;
+                //~ number best_right_cross = 0;
+                //~ point bestleft, bestright;
+                point ab = center(lineA, lineB, maxc);
+                //~ for (uint j = 0; j < aux; j++)
+                //~ {
+                        //~ if (maxc == polygon[j])
+                                //~ continue;
+                        //~ number product = cross(maxc, ab, polygon[j]);
+                        //~ if (best_left_cross > product)
+                        //~ {
+                                //~ best_left_cross = product;
+                                //~ bestleft = polygon[j];
+                        //~ }
+                        //~ if (best_right_cross < product)
+                        //~ {
+                                //~ best_right_cross = product;
+                                //~ bestright = polygon[j];
+                        //~ }
+                //~ }
+                
                 number left = 0.0; // product < 0
                 number right = 0.0; // product > 0
-                point ab = center(lineA, lineB, maxc);
+                //~ {
+                        //~ point c = center(maxc, ab, bestleft);
+                        //~ left = dist(c, bestleft);
+                //~ }
+                //~ {
+                        //~ point c = center(maxc, ab, bestright);
+                        //~ right = dist(c, bestright);
+                //~ }
+                
                 for (uint j = 0; j < aux; j++)
                 {
-                        if (maxc == polygon[j])
-                                continue;
-                        
                         point c = center(maxc, ab, polygon[j]);
-                        number d = dist(c, polygon[j]);
                         number product = cross(maxc, ab, polygon[j]);
+                        number d = halfdist(c, polygon[j]);
                         if (product < 0)
                                 left = std::max(left, d);
@@ -144,5 +174,6 @@
                 //~ printf("current minwidth: %Lf\n", minwidthoverall);
                 //~ printf("maxwidthforoneside: %Lf, left: %Lf, right: %Lf\n", maxwidthforoneside, left, right);
-                minwidthoverall = std::min(minwidthoverall, maxwidthforoneside * 2 + (left + right) * 2);
+                number candidate = sqrt(maxwidthforoneside) * 2 + (sqrt(left) + sqrt(right)) * 2;
+                minwidthoverall = std::min(minwidthoverall, candidate);
                 //~ printf("new minwidth: %Lf\n\n", minwidthoverall);
         }