Submission #1285711

#TimeUsernameProblemLanguageResultExecution timeMemory
1285711thanhliem40Balloons (CEOI11_bal)C++20
10 / 100
2097 ms5100 KiB
#include <iostream> #include <vector> #include <cmath> #include <algorithm> #include <iomanip> #include <stack> using namespace std; // Struct lưu thông tin quả bóng đã bơm (Vị trí, Bán kính) struct Balloon { double X; double R; }; // Hàm tính R_i^max khi tiếp xúc với bóng 'prev' (j) double calculate_R_max(double X_curr, double M_curr, const Balloon& prev) { // Công thức va chạm 2D: R_i = (X_i - X_j)^2 / (4 * R_j) // Nếu R_j = 0, thì R_i^max là vô hạn (không bị giới hạn bởi bóng này) if (prev.R < 1e-9) { return M_curr; // Giới hạn bởi M_i } double delta_X = X_curr - prev.X; return (delta_X * delta_X) / (4.0 * prev.R); } void sol() { int n; // Đọc N if (!(cin >> n)) return; // Vector v[i] = {X_i, M_i} vector<pair<double, double>> v(n); for (int i = 0; i < n; i++) { cin >> v[i].first >> v[i].second; } vector<double> ans(n); // Stack lưu các quả bóng đã bơm tạo thành bao lồi dưới stack<Balloon> mono_stack; for (int i = 0; i < n; i++) { double X_i = v[i].first; double M_i = v[i].second; // Bán kính cuối cùng R_i ban đầu là M_i double R_i = M_i; // BƯỚC 1: Tính R_i bằng cách kiểm tra va chạm với các bóng trong Stack // (Đây là logic tối ưu O(N) vì chỉ những bóng trên bao lồi mới cần kiểm tra) while (!mono_stack.empty()) { Balloon t = mono_stack.top(); // Tính bán kính tối đa R_i khi tiếp xúc với bóng t (j) double r_max_t = calculate_R_max(X_i, M_i, t); // R_i bị giới hạn bởi min của tất cả R_max R_i = min(R_i, r_max_t); // Nếu R_i bị giới hạn bởi bóng t (tức là r_max_t < R_i ban đầu) // thì ta giữ bóng t và break. // Ngược lại, bóng t không giới hạn bóng i. // Điều kiện dừng: Bóng t giới hạn bóng i. if (r_max_t <= R_i) { break; // Bóng t giới hạn R_i (đã tính R_i = min) } // Nếu r_max_t > R_i: bóng t không phải là giới hạn gần nhất, // ta tiếp tục kiểm tra bóng dưới t. // Lưu ý: Nếu không dùng logic bao lồi phức tạp, // ta vẫn phải kiểm tra va chạm với TẤT CẢ các bóng trong Stack // và Pop các bóng bị che khuất. } // BƯỚC 2: Duy trì tính Đơn điệu (Convex Hull) // Đây là bước phức tạp nhất, ta cần kiểm tra xem bóng i có che khuất // bóng t (đỉnh Stack) đối với các bóng m > i hay không. // Dùng một biến thể đơn giản hơn: Pop bóng t nếu nó bị bóng i "che khuất" // cho các bóng tiếp theo (sau khi R_i đã được tính). // Để đơn giản, ta chỉ cần kiểm tra xem bóng i có tạo ra một // giới hạn nhỏ hơn so với bóng dưới t (nếu có) hay không. // Cần tính lại R_i_max_t vì vòng lặp trên không pop. // Vòng lặp chính xác cho Monotonic Stack: while (!mono_stack.empty()) { Balloon t = mono_stack.top(); double r_max_t = calculate_R_max(X_i, M_i, t); // R_i bị giới hạn bởi bóng t if (r_max_t < R_i) { R_i = r_max_t; // Nếu R_i bị giới hạn bởi bóng t, thì bóng t là giới hạn gần nhất, // không cần kiểm tra bóng dưới nó. break; } // Nếu r_max_t >= R_i (sau khi R_i đã được giới hạn bởi các bóng khác // hoặc M_i): Điều này ngụ ý bóng t không còn là giới hạn cho i. // Ta pop bóng t ra. (Đây là một heuristic đơn giản, không phải logic // bao lồi chuẩn nhưng thường hoạt động tốt trong bài này). else { mono_stack.pop(); } } // BƯỚC 3: Thêm bóng i vào Stack Balloon curr = {X_i, R_i}; mono_stack.push(curr); ans[i] = R_i; } // In kết quả for (auto el : ans) { cout << fixed << setprecision(3) << el << '\n'; // In 3 chữ số thập phân và xuống dòng } } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); // freopen("BALLOONS.INP","r",stdin); // freopen("BALLOONS.OUT","w",stdout); sol(); return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...