zoukankan      html  css  js  c++  java
  • P1337 [JSOI2004]平衡点 / 吊打XXX

    [JSOI2004]平衡点 / 吊打XXX

    题目描述

    如图:有n个重物,每个重物系在一条足够长的绳子上。每条绳子自上而下穿过桌面上的洞,然后系在一起。图中X处就是公共的绳结。假设绳子是完全弹性的(不会造成能量损失),桌子足够高(因而重物不会垂到地上),且忽略所有的摩擦。 问绳结X最终平衡于何处。 注意:桌面上的洞都比绳结X小得多,所以即使某个重物特别重,绳结X也不可能穿过桌面上的洞掉下来,最多是卡在某个洞口处。 ![](https://cdn.luogu.org/upload/pic/148.png)

    输入输出格式

    输入格式

    文件的第一行为一个正整数n(1≤n≤1000),表示重物和洞的数目。接下来的n行,每行是3个整数:Xi.Yi.Wi,分别表示第i个洞的坐标以及第 i个重物的重量。(-10000≤x,y≤10000, 0<w≤1000 )

    输出格式

    你的程序必须输出两个浮点数(保留小数点后三位),分别表示处于最终平衡状态时绳结X的横坐标和纵坐标。两个数以一个空格隔开。

    输入输出样例

    输入样例 #1

    3
    0 0 1
    0 2 1
    1 1 1

    输出样例 #1

    0.577 1.000

    说明

    [JSOI]
     
    [思路]  模拟退火

    一、模拟退火步骤

      基础知识点这里

    二、模拟退火注意事项

    1. 温度T的初始值设置问题。 初始温度高,则搜索到全局最优解的可能性大,但因此要花费大量的计算时间;反之,则可节约计算时间,但全局搜索性能可能受到影响。

    2. 退火速度问题。 模拟退火算法的全局搜索性能也与退火速度密切相关。同一温度下的“充分”搜索(退火)是相当必要的,但这需要计算时间。

    3. 温度管理问题 降温系数应为正的略小于1.00的常数。

    关于这道题,一切自然变化进行的方向都是使能量降低,因为能量较低的状态比较稳定。

    因为物重一定,绳子越短,重物越低,势能越小,势能又与物重成正比,所以,只要使得$sum_{i=1}^ndist[i]*weight[i]$也就是总的重力势能最小,就可以使系统平衡

     
    [代码]
     
    #include<cmath>
    #include<ctime>
    #include<cstdio>
    #include<algorithm>
    #define pf(x) ((x)*(x))
    using namespace std;
    const int N=1005;
    int n;struct node{double x,y,z;}a[N];double ansx,ansy,answ=1e9;
    inline double energy(double nx,double ny){
        double res=0;
        for(int i=1;i<=n;i++) res+=sqrt(pf(nx-a[i].x)+pf(ny-a[i].y))*a[i].z;
        return res;
    }
    inline void SA(){
        for(double T=1e5;T>=1e-14;T*=0.977){
            double tx=ansx+(rand()*2-RAND_MAX)*T;
            double ty=ansy+(rand()*2-RAND_MAX)*T;
            double tw=energy(tx,ty);
            if(tw<answ){
                ansx=tx;
                ansy=ty;
                answ=tw;
            }
            else if(exp(-(tw-answ)/T)*RAND_MAX>rand()){
                ansx=tx;
                ansy=ty;
            }
        }
    }
    int main(){
        srand(time(0)),srand(rand()+2000329);
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].z),ansx+=a[i].x,ansy+=a[i].y;
        answ=energy(ansx/=1.0*n,ansy/=1.0*n);
        while((clock()/(1.0*CLOCKS_PER_SEC))<=0.977) SA();
        printf("%.3lf %.3lf
    ",ansx,ansy);
        return 0;
    }
  • 相关阅读:
    LeetCode "Super Ugly Number" !
    LeetCode "Count of Smaller Number After Self"
    LeetCode "Binary Tree Vertical Order"
    LeetCode "Sparse Matrix Multiplication"
    LeetCode "Minimum Height Tree" !!
    HackerRank "The Indian Job"
    HackerRank "Poisonous Plants"
    HackerRank "Kundu and Tree" !!
    LeetCode "Best Time to Buy and Sell Stock with Cooldown" !
    HackerRank "AND xor OR"
  • 原文地址:https://www.cnblogs.com/shenben/p/11342217.html
Copyright © 2011-2022 走看看