模拟退火大法6
模拟退火
随机圆心的位置即可
调参路漫漫
#include
#include
#include
#define rep(i, j, k) for (register int i = j; i <= k; i++)
#define _rep(i, j, k) for (register int i = k; i >= j; i--)
#define _b_pct __builtin_popcount
using ll = long long;
using db = double;
using namespace std;
const int N = 2e4+ 7, M = 2e6+7, K = 16, INF = 1e9;
const ll inv2 = 499122177, LLF = 1e16, mod = 1e9+7;
const db eps=1e-6;
int n,m,ans;
db X,Y,R;
struct Pos {
db x,y,r;
}p[N],em[N];
ll qpow(ll ba, ll pow) {
ll res = 1;
while (pow) {
if (pow & 1)
res = res * ba % mod;
ba = ba * ba % mod, pow >>= 1;
}
return res;
}
ll Add(ll x, ll y) { return ((x + y) % mod); }
ll Mul(ll x, ll y) { return ((x * y) % mod); }
ll Del(ll x, ll y) { return (x - y < 0 ? x - y + mod : x - y); }
ll Inv(ll x) { return qpow(x, mod - 2); }
ll Block(ll x) {
ll res = 0;
for (ll l = 1, r; l <= x; l = r + 1) {
r = x / (x / l);
res = Add(res, Mul((x / l), (r - l + 1)));
}
return res;
}
db Rand() { return (db)rand()/RAND_MAX; }
db solve(db xx,db yy) {
int tmp=0; db len=INF;
rep(i,1,n) {
db tx=p[i].x-xx,ty=p[i].y-yy;
len=fmin(len,sqrt(tx*tx+ty*ty)-p[i].r);
}
len=fmin(len,R);
if(len<0) tmp=0;
else {
rep(i,1,m) {
db tx=em[i].x-xx,ty=em[i].y-yy;
if(len>=sqrt(tx*tx+ty*ty)) tmp++;
}
}
if(tmp>ans) ans=tmp,X=xx,Y=yy;
return tmp;
}
void SA() {
db t=300076;
db nx=X,ny=Y;
while(t>0.000150) {
db tx=nx+t*(Rand()*2-1),ty=ny+t*(Rand()*2-1);
db delta=solve(tx,ty)-solve(nx,ny);
if(exp(-delta/t)