bzoj3680: 吊打XXX

Posted Nico&11101001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3680: 吊打XXX相关的知识,希望对你有一定的参考价值。

题目链接

bzoj3680: 吊打XXX

题解

物理题
问题转化为求力的重心
模拟退火即可

代码

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
const int maxn = 100007;
double x[maxn],y[maxn],w[maxn]; 
int n;double ansx,ansy,nowx,nowy,Ans = 1.0 * 1e18;
double calc(double X,double Y) {
    double ret = 0; 
    for(int i = 1;i <= n;++ i) 
        ret += w[i] * sqrt((X - x[i]) * (X - x[i]) + (Y - y[i]) * (Y - y[i]));
    if(ret < Ans) Ans = ret,ansx = X,ansy = Y;
    return ret;
}
double Random() {return (double) rand() / RAND_MAX;} 
void SA(double T) {
    nowx = ansx,nowy = ansy;
    double tmpx ,tmpy;
    while(T > 0.001) {
        tmpx = nowx + T * (Random() * 2 - 1);
        tmpy = nowy + T * (Random() * 2 - 1); 
        double DE = calc(nowx,nowy) - calc(tmpx,tmpy); 
        if(DE > 0 || Random() <= exp(DE/T)) 
            nowx = tmpx,nowy = tmpy;
        T *= 0.98;
    } 
     
    for(int i = 1;i <= 1000;++ i) {
        tmpx = ansx + T * (Random() * 2 - 1) ; 
        tmpy = ansy + T * (Random() * 2 - 1) ; 
        calc(tmpx,tmpy); 
    } 
}
int main() {
    srand(19260817); 
    scanf("%d",&n);
    for(int i = 1;i <= n;++ i) scanf("%lf%lf%lf",x + i,y + i,w + i),
        ansx += x[i],ansy += y[i]; 
    ansx /= n;ansy /= n;  
    //printf("%lf %lf\n",Ans,ansy);
    SA(40000001); 
    printf("%.3lf %.3lf",ansx,ansy); 
    return 0; 
}

以上是关于bzoj3680: 吊打XXX的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ3680吊打XXX(模拟退火)

bzoj3680: 吊打XXX

bzoj3680 吊打XXX

BZOJ3680吊打XXX 模拟退火

BZOJ3680吊打xxx [模拟退火]

BZOJ 3680: 吊打XXX模拟退火算法裸题学习,爬山算法学习