fork download
  1. #include <iostream>
  2. #include <map>
  3. #include <set>
  4. #include <cmath>
  5. #include <random>
  6. #include <tuple>
  7. #include <chrono>
  8.  
  9. //boilerplate point/vector class
  10. template<typename T>
  11. struct Point
  12. {
  13. T x, y;
  14. Point(T x = T{}, T y = T{}) noexcept
  15. : x{x}
  16. , y{y}
  17. {
  18. }
  19. Point(Point const &) noexcept = default;
  20. Point(Point &&) noexcept = default;
  21. Point &operator=(Point const &) noexcept = default;
  22. Point &operator=(Point &&) noexcept = default;
  23.  
  24. template<typename U>
  25. Point &operator*=(U const &u) noexcept
  26. {
  27. x = static_cast<T>(x*u);
  28. y = static_cast<T>(y*u);
  29. return *this;
  30. }
  31. template<typename U>
  32. friend Point operator*(Point const &p, U const &u) noexcept
  33. {
  34. return Point{p} *= u;
  35. }
  36. template<typename U>
  37. friend Point operator*(U const &u, Point const &p) noexcept
  38. {
  39. return Point{p} *= u;
  40. }
  41. template<typename U>
  42. Point &operator/=(U const &u) noexcept
  43. {
  44. x = static_cast<T>(x/u);
  45. y = static_cast<T>(y/u);
  46. return *this;
  47. }
  48. template<typename U>
  49. friend Point operator/(Point const &p, U const &u) noexcept
  50. {
  51. return Point{p} /= u;
  52. }
  53. template<typename U>
  54. friend Point operator/(U const &u, Point const &p) noexcept
  55. {
  56. return Point{p} /= u;
  57. }
  58. Point &operator+=(Point const &p) noexcept
  59. {
  60. x += p.x;
  61. y += p.y;
  62. return *this;
  63. }
  64. friend Point operator+(Point const &a, Point const &b) noexcept
  65. {
  66. return Point{a} += b;
  67. }
  68. Point &operator-=(Point const &p) noexcept
  69. {
  70. x -= p.x;
  71. y -= p.y;
  72. return *this;
  73. }
  74. friend Point operator-(Point const &a, Point const &b) noexcept
  75. {
  76. return Point{a} -= b;
  77. }
  78.  
  79. friend bool operator==(Point const &a, Point const &b) noexcept
  80. {
  81. return std::tie(a.x, a.y) == std::tie(b.x, b.y);
  82. }
  83. friend bool operator<(Point const &a, Point const &b) noexcept
  84. {
  85. return std::tie(a.x, a.y) < std::tie(b.x, b.y);
  86. }
  87.  
  88. friend std::ostream &operator<<(std::ostream &o, Point const &p) noexcept
  89. {
  90. return o << '(' << p.x << ", " << p.y << ')';
  91. }
  92. };
  93.  
  94. using real_point = Point<double>;
  95. using int_point = Point<long long>;
  96.  
  97. int_point cast(real_point const &p)
  98. {
  99. return {static_cast<long long>(std::floor(p.x)), static_cast<long long>(std::floor(p.y))};
  100. }
  101.  
  102. int main()
  103. {
  104. std::size_t num_points;
  105. std::cin >> num_points;
  106. double radius;
  107. std::cin >> radius;
  108.  
  109. std::mt19937 gen {std::random_device{}()};
  110. std::uniform_real_distribution<double> dist {-radius, radius};
  111.  
  112. std::set<real_point> points;
  113. while(points.size() < num_points)
  114. {
  115. points.emplace(dist(gen), dist(gen));
  116. }
  117.  
  118. std::multimap<int_point, real_point> grid;
  119. for(auto const &p : points)
  120. {
  121. grid.emplace(cast(p), p);
  122. }
  123.  
  124. long long r_min = static_cast<long long>(std::floor(-radius*2.0));
  125. long long r_max = static_cast<long long>(std::ceil(radius*2.0));
  126. std::set<std::set<real_point>> solutions;
  127. auto start = std::chrono::high_resolution_clock::now();
  128. {
  129. for(auto it = std::begin(grid); it != std::end(grid); ++it)
  130. {
  131. auto const &a = it->second;
  132. auto jt = it;
  133. for(++jt; jt != std::end(grid); ++jt)
  134. {
  135. auto const &b = jt->second;
  136. auto slope = b - a;
  137. auto const abs = std::sqrt(slope.x*slope.x + slope.y*slope.y);
  138. slope /= abs;
  139.  
  140. std::set<real_point> coincidences;
  141. coincidences.emplace(a);
  142. coincidences.emplace(b);
  143. for(auto r = r_min; r < r_max; ++r)
  144. {
  145. auto sector = grid.equal_range(cast(a + slope*r));
  146. for(auto kt = sector.first; kt != sector.second; ++kt)
  147. {
  148. auto const &c = kt->second;
  149. if(c == a || c == b)
  150. {
  151. continue;
  152. }
  153. auto slope2 = c - a;
  154. auto const abs2 = std::sqrt(slope2.x*slope2.x + slope2.y*slope2.y);
  155. slope2 /= abs2;
  156. slope2 -= slope;
  157. if(std::abs(slope2.x) < 0.0001 && std::abs(slope2.y) < 0.0001)
  158. {
  159. coincidences.emplace(c);
  160. }
  161. }
  162. }
  163. if(coincidences.size() >= 4)
  164. {
  165. solutions.emplace(std::move(coincidences));
  166. }
  167. }
  168. }
  169. }
  170. auto end = std::chrono::high_resolution_clock::now();
  171. std::chrono::duration<double> diff = end - start;
  172. std::cout << std::endl << "Time spent searching: " << diff.count() << 's' << std::endl;
  173. for(auto const &coincidences : solutions)
  174. {
  175. for(auto const &p : coincidences)
  176. {
  177. std::cout << p << " ";
  178. }
  179. std::cout << std::endl;
  180. }
  181. }
  182.  
Success #stdin #stdout 1.22s 3284KB
stdin
500
10
stdout
Time spent searching: 1.23143s
(-9.99733, -5.56257) (0.100705, -0.955198) (7.29076, 2.32708) (9.80284, 3.4721) 
(-9.98776, -6.03642) (-0.00178075, -2.98621) (2.95863, -2.08072) (5.29602, -1.36909) 
(-9.86204, -7.92571) (-7.06671, -2.30064) (-5.86297, 0.122809) (-3.83204, 4.21066) 
(-9.74468, 8.1403) (-0.26996, -3.4223) (1.07528, -5.06359) (1.50451, -5.58808) 
(-9.74468, 8.1403) (0.981174, 8.32396) (6.29261, 8.41354) (9.40576, 8.46681) 
(-9.65531, 9.10318) (4.63175, 8.64355) (7.94749, 8.53902) (9.6277, 8.48446) 
(-9.62323, -6.5807) (-5.38753, -0.628196) (0.589703, 7.76953) (0.981174, 8.32396) 
(-9.28424, -7.82599) (-3.71333, 4.26027) (-1.56687, 8.91325) (-1.4089, 9.26064) 
(-9.09996, -3.4638) (-4.30248, 1.56174) (-3.70144, 2.18989) (0.328572, 6.41479) 
(-9.06268, 3.17556) (-1.78229, -3.60138) (-0.113935, -5.15591) (4.47068, -9.42649) 
(-8.98401, -4.33371) (3.93888, 3.81783) (7.27987, 5.92371) (9.62388, 7.40405) 
(-8.89937, -1.23462) (-6.17548, -2.59484) (2.30061, -6.82809) (7.94164, -9.64418) 
(-8.62558, 3.43756) (-2.74975, 1.32173) (-1.01785, 0.697835) (0.5813, 0.12189) 
(-8.46146, -6.03921) (-3.71333, 4.26027) (-1.56687, 8.91325) (-1.4089, 9.26064) 
(-8.23436, 8.17771) (-4.32822, 5.42166) (-1.78733, 3.62997) (5.29602, -1.36909) 
(-8.08125, 9.59795) (0.365025, 9.06765) (4.57405, 8.80174) (9.6277, 8.48446) 
(-7.88104, -1.16249) (-1.51876, 5.49373) (-1.2826, 5.73986) (-1.24522, 5.77894) 
(-7.76082, 7.74252) (-4.91031, 4.64547) (4.40671, -5.47749) (5.68446, -6.86635) 
(-7.76082, 7.74252) (2.678, 7.62549) (7.44018, 7.57338) (9.70094, 7.54984) 
(-7.25915, -6.84046) (2.40443, 4.43166) (4.4791, 6.85246) (7.16543, 9.98518) 
(-7.20077, -1.83534) (-4.2186, -3.37325) (-3.29488, -3.85017) (7.94164, -9.64418) 
(-7.1189, -9.8101) (4.60033, -1.73342) (5.29006, -1.25694) (9.43984, 1.60163) 
(-7.1189, -9.8101) (6.58778, -2.31775) (7.72211, -1.69665) (9.02182, -0.984856) 
(-6.76025, -8.49502) (-3.0536, -4.42727) (3.97399, 3.28435) (4.34339, 3.68767) 
(-6.06943, 7.12541) (-4.16121, 6.84736) (8.54878, 4.99447) (9.2304, 4.89447) 
(-5.86235, 4.79312) (2.678, 7.62549) (4.50838, 8.23147) (7.26743, 9.14601) 
(-5.75964, -0.666523) (-0.119362, 3.58091) (6.29261, 8.41354) (7.26743, 9.14601) 
(-5.73061, 9.32044) (-4.91031, 4.64547) (-3.23013, -4.93852) (-2.50641, -9.0506) 
(-5.36645, 6.39056) (2.30061, -6.82809) (2.91965, -7.89782) (2.95612, -7.95656) 
(-5.18478, -6.97843) (0.100705, -0.955198) (6.00766, 5.77396) (8.6121, 8.74463) 
(-5.08572, -7.09812) (-2.46263, -6.3099) (-0.717761, -5.78516) (8.37638, -3.05132) 
(-4.77058, -3.57681) (9.51355, 8.39161) (9.6277, 8.48446) (9.64706, 8.50171) 
(-4.31998, 9.18367) (-0.798143, -3.8089) (-0.284932, -5.70663) (0.241176, -7.6538) 
(-4.29487, -7.11982) (-3.91942, -6.0207) (0.328572, 6.41479) (0.981174, 8.32396) 
(-3.45212, -1.0353) (-0.00178075, -2.98621) (4.40671, -5.47749) (7.05373, -6.97412) 
(-3.23013, -4.93852) (-0.113935, -5.15591) (0.351751, -5.18868) (6.13835, -5.59322) 
(-2.65349, 3.0615) (-0.798143, -3.8089) (-0.284932, -5.70663) (0.241176, -7.6538) 
(-1.94823, -2.71319) (3.37482, 4.13454) (6.4959, 8.15177) (7.26743, 9.14601) 
(-1.8587, -4.09391) (4.34339, 3.68767) (6.00766, 5.77396) (7.44018, 7.57338) 
(-1.83257, -1.24287) (3.51638, 3.29621) (9.6277, 8.48446) (9.64706, 8.50171) 
(-1.81157, 6.49996) (-0.566018, -6.30204) (-0.502085, -6.96898) (-0.414042, -7.8531) 
(-1.72842, -7.22689) (0.0773688, -5.68726) (3.94487, -2.39067) (9.07714, 1.98517) 
(-0.954481, -5.56305) (4.60033, -1.73342) (5.29006, -1.25694) (9.43984, 1.60163) 
(-0.940551, -5.93213) (1.59338, 8.39051) (1.66672, 8.81649) (1.8305, 9.73393) 
(-0.824197, -5.24776) (1.59338, 8.39051) (1.66672, 8.81649) (1.8305, 9.73393) 
(-0.546475, 7.32195) (0.240007, -3.6258) (0.351751, -5.18868) (0.536403, -7.74022) 
(-0.439133, 5.81992) (0.240007, -3.6258) (0.351751, -5.18868) (0.536403, -7.74022) 
(0.379605, -5.74323) (3.22855, 3.89635) (4.50838, 8.23147) (4.63175, 8.64355) 
(0.625775, 1.1379) (9.51355, 8.39161) (9.6277, 8.48446) (9.64706, 8.50171) 
(1.76322, 2.07684) (9.51355, 8.39161) (9.6277, 8.48446) (9.64706, 8.50171) 
(3.93888, 3.81783) (9.51355, 8.39161) (9.6277, 8.48446) (9.64706, 8.50171) 
(4.40671, -5.47749) (5.05997, 2.76635) (5.47513, 7.97944) (5.60904, 9.68255)