#include using namespace std; #define sq(a) pow(a, 2) #define gettick() chrono::duration_cast(chrono::high_resolution_clock::now().time_since_epoch()).count() struct vec2 { int x = 0; int y = 0; int64_t priority = 0; int index = 0; }; // vec2 contains x y and priority for selecting as starting point struct result { int amount_of_circles = 0; unordered_map circles; }; // result structure, has circles and amount of circles int n, radius; // n and radius of each circle vec2 points[150000]; // all points, in a custom 2d vector type vec2 points_copy_sorted[150000]; // all points but sorted result best_result; // best result, and our submitted solution uint64_t start_tick = 0; // start tick of program // is there enough time bool is_enough_time() { return (gettick() - start_tick) < 4200; } // see if far away enough bool is_far_away_enough(vec2& a, vec2& b) { if(sq(b.x - a.x) + sq(b.y - a.y) >= sq(radius * 2)) return true; return false; } // calculate result void calculate_result(int starting_point) { // setup result with starting point result our_result; our_result.circles[0] = starting_point; our_result.amount_of_circles++; bool time_ran_out = false; for(int i = 0; i < n; i++) { if(!is_enough_time) { time_ran_out = true; break; } bool is_good_to_be_circle = true; for(int j = 0; j < our_result.amount_of_circles; j++) { if(!is_far_away_enough(points[our_result.circles[j]], points[i])) { is_good_to_be_circle = false; break; } } if(is_good_to_be_circle) { our_result.circles[our_result.amount_of_circles] = i; our_result.amount_of_circles++; } } if(time_ran_out == false && our_result.amount_of_circles > best_result.amount_of_circles) { best_result = our_result; } /*if(time_ran_out == false) { cout << starting_point << " " << points[starting_point].priority << " " << our_result.amount_of_circles << endl; }*/ } int main() { // file I/O start_tick = gettick(); freopen("mars.in", "r", stdin); freopen("mars.out", "w", stdout); // performance funnies std::ios::sync_with_stdio(false); // input basic args cin >> n >> radius; // calculate first result while inputting the point values int64_t average = -1; for(int i = 0; i < n; i++) { cin >> points[i].x >> points[i].y; if(average == -1) { average = sq(points[i].x) + sq(points[i].y); points[i].priority = -1; } else { int64_t new_average = (average + sq(points[i].x) + sq(points[i].y)) / 2; points[i].priority = abs(average - new_average) * (i + 1); } points[i].index = i; bool is_good_to_be_circle = true; for(int j = 0; j < best_result.amount_of_circles; j++) { if(!is_far_away_enough(points[best_result.circles[j]], points[i])) { is_good_to_be_circle = false; break; } } if(is_good_to_be_circle) { best_result.circles[best_result.amount_of_circles] = i; best_result.amount_of_circles++; } } // calculate multiple results and get best one hopefully copy(points, points + n, points_copy_sorted); sort(points_copy_sorted, points_copy_sorted + n, [](vec2& a, vec2& b) { return a.priority > b.priority; }); for(int i = 0; i < n; i++) { if(!is_enough_time()) break; if(points_copy_sorted[i].priority == -1) continue; calculate_result(points_copy_sorted[i].index); } // print out circles and indices of the points that the circles are a center of printf("%d\n", best_result.amount_of_circles); for(int i = 0; i < best_result.amount_of_circles; i++) { printf("%d ", best_result.circles[i] + 1); } printf("\n"); }