// 2024_M5.cpp : This file contains the 'main' function. Program execution begins and ends there. // #include #include #include #include #include #include struct Point { double x, y; }; double dist(const Point& p1, const Point& p2) { return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y); } std::chrono::steady_clock::duration timeout = std::chrono::milliseconds(4900); std::vector alg1(int N, double R2, const std::vector& points) { std::vector result; result.reserve(N); std::list candidates; for (int i = 1; i < N; i++) { candidates.push_back(i); } result.push_back(0); bool added; do { added = false; auto i = candidates.begin(); while (i != candidates.end()) { bool out = true; auto& p = points[*i]; for (auto j : result) { if (dist(p, points[j]) < R2) { out = false; i = candidates.erase(i); break; } } if (out) { result.push_back(*i); i = candidates.erase(i); added = true; } } } while (added); return result; } std::vector alg2(int N, double R2, const std::vector& points, const Point& sp, bool use_sp, std::chrono::steady_clock::time_point start) { std::vector result; result.reserve(N); struct st { int i, j; double m1, m2; }; std::list candidates; for (int i = 0; i < N; i++) { candidates.push_back({ i, 0, 0, 0 }); } auto imin = candidates.begin(); double dmin = dist(sp, points[imin->i]); for (auto it = candidates.begin(); it != candidates.end(); it++) { double d = dist(sp, points[it->i]); if (d < dmin) { imin = it; dmin = d; } } auto cp = use_sp ? sp : points[imin->i]; result.push_back(imin->i); candidates.erase(imin); bool found; do { found = false; auto it = candidates.begin(); while (it != candidates.end()) { bool ok = true; auto& p = points[it->i]; double dm1 = it->m1, dm2 = it->m2; for (int j = it->j; j < result.size(); j++) { auto d = dist(p, points[result[j]]) - R2; if (d < 0) { ok = false; it = candidates.erase(it); break; } if (dm1 == 0) { dm1 = d; } else { if (d < dm1) { dm2 = dm1; dm1 = d; } else if (dm2 == 0 || d < dm2) { dm2 = d; } } } if (ok) { it->j = (int)result.size(); it->m1 = dm1; it->m2 = dm2; double dm = dm1 + dm2 + dist(cp, points[it->i]); if (found) { if (dmin > dm) { imin = it; dmin = dm; } } else { found = true; imin = it; dmin = dm; } ++it; } } if (found) { result.push_back(imin->i); candidates.erase(imin); } } while (found && (std::chrono::steady_clock::now() - start) < timeout); return result; } int main() { std::ifstream fin("mars.in"); const auto start = std::chrono::steady_clock::now(); int N; double R, R2; Point min, max, c; std::vector points; fin >> N >> R; R2 = 4 * R * R; points.reserve(N); std::list> results; for (int i = 0; i < N; i++) { Point p; fin >> p.x >> p.y; points.push_back(p); // find area if (i == 0) { min = max = p; } else { if (min.x > p.x) min.x = p.x; if (max.x < p.x) max.x = p.x; if (min.y > p.y) min.y = p.y; if (max.y < p.y) max.y = p.y; } } c = { (min.x + max.x) / 2, (min.y + max.y) / 2 }; results.push_back(alg1(N, R2, points)); results.push_back(alg2(N, R2, points, c, false, start)); results.push_back(alg2(N, R2, points, c, true, start)); results.push_back(alg2(N, R2, points, min, false, start)); results.push_back(alg2(N, R2, points, min, true, start)); results.push_back(alg2(N, R2, points, max, false , start)); results.push_back(alg2(N, R2, points, max, true, start)); results.sort([](auto& l, auto& r) { return l.size() > r.size(); }); auto& result = results.front(); std::ofstream fout("mars.out"); fout << result.size() << std::endl; for (int i = 0; i < result.size(); i++) { if (i > 0) fout << " "; fout << result[i] + 1; } fout << std::endl; }