답안 #1047798

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1047798 2024-08-07T16:02:42 Z Requiem Balloons (CEOI11_bal) C++17
100 / 100
124 ms 19908 KB
#include<bits/stdc++.h>
#define int long long
#define double long double
#define pb push_back
#define fast ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
#define MOD 1000000007
#define inf 1e18
#define fi first
#define se second
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FORD(i,a,b) for(int i=a;i>=b;i--)
#define sz(a) ((int)(a).size())
#define endl '\n'
#define pi 3.14159265359
#define TASKNAME "balloon"
using namespace std;

/**Debugging Tool  **/
void __print(int x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
//void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}

template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}

void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}

#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif

/*----------------------------------*/

/**  Vector nhieu chieu **/
template<int D, typename T>
struct Vec: public vector<Vec<D - 1, T>>{
     static_assert(D >= 1, "vector dimensions must be greater than 0");
     template<typename... Args>
     Vec(int n = 0, Args... args): vector<Vec<D - 1, T>>(n, Vec<D - 1, T>(args...)){
     }
};

template<typename T>
struct Vec<1, T>: public vector<T> {
    Vec(int n = 0, const T& val = T()): vector<T>(n, val) {};
};
/*--------------------------------*/

template<typename T> bool maximize(T &res, const T &val) { if (res < val){ res = val; return true; }; return false; }
template<typename T> bool minimize(T &res, const T &val) { if (res > val){ res = val; return true; }; return false; }
typedef pair<int,int> ii;
typedef pair<int,ii> iii;
typedef vector<int> vi;
#define eps 1e-4
/**
 * Cho n quả bóng với 2 thông số là Xi và Ri, tương ứng là vị trí bơm và bán kính bơm tối đa.
 * Ta bơm tuần tự từ quả bóng thứ 1 đến quả bóng thứ n.
 * Với quả bóng thứ i, ta bơm cho đến khi nó chạm vào quả bóng khác hoặc nó đạt bán kính tối đa
 * Giả sử ta đang có cấu hình là (x1, r1), (x2, r2), ... Khi thêm vào (xn, rn) thì bài toán
 sẽ thay đổi ntn
 * Với n <= 2000, ta có thể duyệt n^2 để tìm ra bán kính của quả bóng
 *
 * bằng cách lấy min((x - xj)^2 / (4 * rj))
 * Khi n lớn lên, ta sẽ cần một cách làm thông minh hơn bằng cách chỉ duyệt qua những vị trí cần thiết.
 * Một cách visual, ta thấy rằng ta đơn giản là giả sử rằng mình bơm bóng đến hết cỡ thì liệu hình tròn đó
 * sẽ giao với những đường nào.
 * Nếu nó không giao thì ok
 * Nếu nó giao thì ta phải thu nhỏ nó lại
 */

const int MAXN = 3e5 + 9;

struct balloon{
    int position;
    int maxDiameter;
} B[MAXN];

int n;

void input(){
    cin >> n;
    for(int i = 1; i <= n; i++){
        cin >> B[i].position >> B[i].maxDiameter;
    }

}
namespace subtask1{
    bool check(){
        return n <= 2000;
    }

    double currentDiameter[MAXN];
    //1 vị trí là không cần thiết nếu như sau có thằng lớn hơn nó.

    void solve(){
        for(int i = 1; i <= n; i++){
            if (i == 1) currentDiameter[i] = B[i].maxDiameter;
            else{
                currentDiameter[i] = B[i].maxDiameter;
                for(int j = 1; j < i; j++){
                    int x1 = B[j].position;
                    int x2 = B[i].position;
                    minimize(currentDiameter[i], 1.0 * (x1 - x2) * (x1 - x2) / (4 * currentDiameter[j]));
                    debug(1.0 * (x1 - x2) * (x1 - x2) / (4 * currentDiameter[j]));
                }
            }
            cout << setprecision(3) << fixed << currentDiameter[i] << endl;
        }
        cout << endl;
    }
}

namespace subtask2{
    bool check(){
        return n <= 20000;
    }
    vector<int> stk;
    double currentDiameter[MAXN];

    double calc(double x1, double x2, double r1){
        return (x1 - x2) * (x1 - x2) / (4 * r1);
    }
    void solve(){
        for(int i = 1; i <= n; i++){
            if (i == 1) {
                currentDiameter[i] = B[i].maxDiameter;
                stk.pb(i);
            }
            else{
                currentDiameter[i] = B[i].maxDiameter;
                for(int j = 0; j < stk.size(); j++){
                    int x1 = B[stk[j]].position;
                    int x2 = B[i].position;
                    minimize(currentDiameter[i], 1.0 * (x1 - x2) * (x1 - x2) / (4 * currentDiameter[stk[j]]));
                    double c = 1.0 * (x1 - x2) * (x1 - x2) / (4.0 * currentDiameter[stk[j]]);
                    cout << setprecision(3) << "?"<<fixed << (x1 - x2) * (x1 - x2) / (4.0 * currentDiameter[stk[j]]) << endl;
                }
                cout << endl;
                while(!stk.empty() and currentDiameter[i] > currentDiameter[stk.back()] + eps){
                     stk.pop_back();
                }
                stk.pb(i);
            }
            cout << setprecision(3) << fixed << currentDiameter[i] << endl;
        }
        cout << endl;
    }
}
namespace subtask3{
    bool check(){
        return true;
    }

    vector<int> stk;
    double currentDiameter[MAXN];

    void solve(){
        for(int i = 1; i <= n; i++){
            if (i == 1) {
                currentDiameter[i] = B[i].maxDiameter;
                stk.pb(i);
            }
            else{
                currentDiameter[i] = B[i].maxDiameter;
                while(!stk.empty()){
                    int id = stk.back();
                    double cur = min(currentDiameter[i], 1.0L * ((B[id].position - B[i].position) * (B[id].position - B[i].position) / (4 * currentDiameter[id])));
                    minimize(currentDiameter[i], cur);
                    if (cur >= currentDiameter[id]) stk.pop_back();
                    else break;
                }
                if (!stk.empty()){
                    int id = stk.back();
                    double cur = min(1.0L * B[i]. maxDiameter, 1.0L * ((B[id].position - B[i].position) * (B[id].position - B[i].position) / (4 * currentDiameter[id])));
                    minimize(currentDiameter[i], cur);
                }
                stk.pb(i);


            }
            cout << setprecision(3) << fixed << currentDiameter[i] << endl;
        }
        cout << endl;
    }
}
main()
{
    fast;
    if (fopen(TASKNAME".inp","r")){
        freopen(TASKNAME".inp","r",stdin);
        freopen(TASKNAME".out","w",stdout);
    }
    input();
    // if (subtask1::check()) return subtask1::solve(), 0;
//    subtask2::solve();
    if (subtask3::check()) return subtask3::solve(), 0;
}
/**
Warning:
- MLE / TLE?
- Gioi han mang?
- Gia tri max phai luon gan cho -INF
- long long co can thiet khong?
- tran mang.
- code can than hon
- Nho sinh test de tranh RTE / TLE

--> Coi lai truoc khi nop
**/

Compilation message

bal.cpp: In function 'void subtask2::solve()':
bal.cpp:146:34: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  146 |                 for(int j = 0; j < stk.size(); j++){
      |                                ~~^~~~~~~~~~~~
bal.cpp:150:28: warning: unused variable 'c' [-Wunused-variable]
  150 |                     double c = 1.0 * (x1 - x2) * (x1 - x2) / (4.0 * currentDiameter[stk[j]]);
      |                            ^
bal.cpp: At global scope:
bal.cpp:201:1: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
  201 | main()
      | ^~~~
bal.cpp: In function 'int main()':
bal.cpp:205:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  205 |         freopen(TASKNAME".inp","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
bal.cpp:206:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  206 |         freopen(TASKNAME".out","w",stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 6492 KB 10 numbers
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 6492 KB 2 numbers
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 6488 KB 505 numbers
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 6492 KB 2000 numbers
# 결과 실행 시간 메모리 Grader output
1 Correct 11 ms 8796 KB 20000 numbers
# 결과 실행 시간 메모리 Grader output
1 Correct 36 ms 11440 KB 50000 numbers
2 Correct 18 ms 11192 KB 49912 numbers
# 결과 실행 시간 메모리 Grader output
1 Correct 42 ms 11860 KB 100000 numbers
# 결과 실행 시간 메모리 Grader output
1 Correct 49 ms 11856 KB 115362 numbers
2 Correct 41 ms 11424 KB 119971 numbers
# 결과 실행 시간 메모리 Grader output
1 Correct 65 ms 14164 KB 154271 numbers
2 Correct 124 ms 19896 KB 200000 numbers
# 결과 실행 시간 메모리 Grader output
1 Correct 82 ms 16460 KB 200000 numbers
2 Correct 71 ms 19908 KB 199945 numbers