100ptsUAC,求卡常或指错
查看原帖
100ptsUAC,求卡常或指错
300370
flyfreemrn楼主2025/6/20 11:55

rt,MnZn 刚学模拟退火写的第一道题,写法和第一篇题解基本一致。

#include<bits/stdc++.h>
using namespace std;
#define LOCAL
#define ll long long
#define db double
#define Ciallo true
#define pir pair <ll,ll>
#define fs first
#define sc second
#define V  1000000000
#define MAXN 1010
#define eps 1e-5
inline ll read(){
    ll f = 1, num = 0;
    char c = getchar();
    while(c < '0' || c > '9'){
        if(c=='-') f = -1;c = getchar();
    }
    while(c>='0'&&c<='9') num = num * 10 + c - '0', c = getchar();
    return num * f;
}

random_device rd;
mt19937 gen(rd());

db flrnd(db L, db R){
    uniform_real_distribution <db> dis(L, R);
    return dis(gen);
}

db x[MAXN],y[MAXN],r[MAXN];
db P[MAXN],Q[MAXN];

db st = 1e12,dlt = 0.9996,ed = 1e-8;
ll n,m;
db R;

db calc(db xx, db yy){
    db res = R;
    for(int i = 1;i <= n; ++i){
        db dis = sqrt((x[i] - xx) * (x[i] - xx) + (y[i] - yy) * (y[i] - yy));
        res = min(res, dis - r[i]);
    }
    return max(0.0, res);
}

db f(db xx, db yy){
    db rs = calc(xx, yy);
    ll res = 0;
    db nr = 1e9;
    for(int i = 1;i <= m; ++i){
        db dis = sqrt((P[i] - xx) * (P[i] - xx) + (Q[i] - yy) * (Q[i] - yy));
        if(rs + eps >= dis){
            ++ res;
        }else{
            nr = min(nr, dis - rs);
        }
    }
    if(!res)return -14.14 * nr;
    else return res * 1.0;
}

int main(){
    #ifdef LOCAL
        freopen("w.in", "r", stdin);
        freopen("w.out", "w", stdout);
    #endif

    n = read(),m = read(),R = read();

    for(int i = 1;i <= n; ++i){
        x[i] = read(),y[i] = read(),r[i] = read();
    }

    for(int i = 1;i <= m; ++i){
        P[i] = read(),Q[i] = read();
    }

    db ans = 0;
    auto get_ans = [&](db idx){
        gen = mt19937(idx);
        db xx = 0.0,yy = 0.0;
        db res = f(xx, yy);
        ans = max(ans, res);
        for(db T = st; T >= ed; T *= dlt){
            // if(1.0 * clock() / CLOCKS_PER_SEC - 0.95 > eps)return;
            // cout << T << " " << xx << " " << yy << " " << res << endl;
            db sx = xx + flrnd(-200.0, 200.0);
            db sy = yy + flrnd(-200.0, 200.0);
            while(sx > 20000 || sx < -20000)sx = xx + flrnd(-200.0, 200.0);
            while(sy > 20000 || sy < -20000)sy = yy + flrnd(-200.0, 200.0);
            db nw = f(sx, sy);
            if(nw - res > eps || flrnd(0.0, 1.0) <= exp((nw - res) / T)){
                xx = sx,yy = sy,res = nw;
            }
            ans = max(ans, res);
        }
    };

    // get_ans(20060617);
    get_ans(12);
    get_ans(998244353);
    get_ans(1919810);
    get_ans(114514);

    int ians = (int)ans;
    cout << max(0, ians) << endl;

    cerr << "Time : " << 1.0 * clock() / CLOCKS_PER_SEC << "s \n";
    return 0;
}

2025/6/20 11:55
加载中...