zoukankan      html  css  js  c++  java
  • BZOJ_3680_吊打XXX_模拟退火

    BZOJ_3680_吊打XXX_模拟退火

    Description

    gty又虐了一场比赛,被虐的蒟蒻们决定吊打gty。gty见大势不好机智的分出了n个分身,但还是被人多势众的蒟蒻抓住了。蒟蒻们将
    n个gty吊在n根绳子上,每根绳子穿过天台的一个洞。这n根绳子有一个公共的绳结x。吊好gty后蒟蒻们发现由于每个gty重力不同,绳
    结x在移动。蒟蒻wangxz脑洞大开的决定计算出x最后停留处的坐标,由于他太弱了决定向你求助。
    不计摩擦,不计能量损失,由于gty足够矮所以不会掉到地上。

    Input

    输入第一行为一个正整数n(1<=n<=10000),表示gty的数目。
    接下来n行,每行三个整数xi,yi,wi,表示第i个gty的横坐标,纵坐标和重力。
    对于20%的数据,gty排列成一条直线。
    对于50%的数据,1<=n<=1000。
    对于100%的数据,1<=n<=10000,-100000<=xi,yi<=100000

    Output

    输出1行两个浮点数(保留到小数点后3位),表示最终x的横、纵坐标。

    Sample Input

    3
    0 0 1
    0 2 1
    1 1 1

    Sample Output

    0.577 1.000


    模拟退火板子题。

    每次随机一个[-K,K]的坐标加到现在的坐标上即可。

    初始最大值要开够,大概1e20这样子。

    记得最后用最优解用末温再扩展若干次减小误差。

    exp(i)表示$e^i$。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <climits>
    #include <cstdlib>
    using namespace std;
    typedef double f2;
    f2 mn=1e20,tmn=1e20;
    int n,G[10500];
    struct Point {
        f2 x,y;
        Point() {}
        Point(f2 x_,f2 y_) :
            x(x_),y(y_) {}
    }ans,a[10500];
    f2 dis(const Point &p1,const Point &p2) {
        return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
    }
    f2 get_ans(const Point &p) {
        int i; f2 re=0;
        for(i=1;i<=n;i++) re+=G[i]*dis(a[i],p);
        if(re<mn) mn=re,ans=p;
        return re;
    }
    f2 Rand() {
        return 1.0*rand()/RAND_MAX;
    }
    void orztuihuo(f2 Bg,f2 Ed,f2 d,Point nowp) {
        // ans=nowp;
        tmn=get_ans(nowp);
        f2 b=Bg;
        for(;b>Ed;b*=d) {
            Point nxt=Point(nowp.x+b*(Rand()*2-1),nowp.y+b*(Rand()*2-1));
            f2 tmp=get_ans(nxt);
            if(tmp<tmn||Rand()<exp((tmn-tmp)/b)) {
                tmn=tmp; nowp=nxt;
            }
        }
        int i;
        for(i=1;i<=1000;i++) {
            get_ans(Point(ans.x+b*(Rand()*2-1),ans.y+b*(Rand()*2-1)));
        }
    }
    int main() {
        srand(19260817); rand();
        scanf("%d",&n);
        int i;f2 x,y;
        for(i=1;i<=n;i++) {
            scanf("%lf%lf%d",&a[i].x,&a[i].y,&G[i]); x+=a[i].x; y+=a[i].y;
        }
        x/=n; y/=n;
        orztuihuo(1e5,0.001,0.993,Point(x,y));
        printf("%.3f %.3f
    ",ans.x,ans.y);
    }
    
  • 相关阅读:
    168. Excel Sheet Column Title
    171. Excel Sheet Column Number
    264. Ugly Number II java solutions
    152. Maximum Product Subarray java solutions
    309. Best Time to Buy and Sell Stock with Cooldown java solutions
    120. Triangle java solutions
    300. Longest Increasing Subsequence java solutions
    63. Unique Paths II java solutions
    221. Maximal Square java solutions
    279. Perfect Squares java solutions
  • 原文地址:https://www.cnblogs.com/suika/p/9240250.html
Copyright © 2011-2022 走看看