zoukankan      html  css  js  c++  java
  • 【洛谷 P1337】[JSOI2004]平衡点 / 吊打XXX (模拟退火)

    题目链接

    正解就算了吧,谁叫我理生化 语数外 政史地都菜呢

    模拟退火真玄学,不知道发生了什么就跑出答案了,原理就算了吧,能用(pianfen)就好。
    当重物平衡时,势能一定是最小的,于是当我随机出一个点时,累加所有重物到这个点的距离乘这个重物的质量的积,这样就能反映势能的相对大小了。
    为什么不用考虑方向?自己脑补脑补就好了,反正平衡时这个东西也一定最小。
    然后就是跑看脸的(SA)了,这个八位质数真神奇,交了很多遍都没过,一交这个就过了。

    #include <cstdio>
    #include <cmath>
    #include <ctime>
    #include <cstdlib>
    const double cut = 0.993;
    const double eps = 1e-14;
    const int MAXN = 1010;
    int n, x[MAXN], y[MAXN], w[MAXN];
    double xx, yy, nowx, nowy, Ans = 1e18;
    double get_E(double X, double Y){
        double ans = 0;
        for(int i = 1; i <= n; ++i){
           xx = X - x[i]; yy = Y - y[i];
           ans += sqrt(xx * xx + yy * yy) * w[i];
        }
        return ans;
    }
    void SA(){
        double T = 1926;
        double nx = nowx, ny = nowy;
        while(T > eps){
          double X = nx + ((rand() << 1) - RAND_MAX) * T;
          double Y = ny + ((rand() << 1) - RAND_MAX) * T;
          double ans = get_E(X, Y);
          double delta = ans - Ans;
          if(delta < 0){
            nx = X; ny = Y;
            nowx = X; nowy = Y;
            Ans = ans;
          }
          else if(exp(-delta / T) * RAND_MAX > rand()) nx = X, ny = Y;
          T *= cut;
        }
    }
    int sx, sy;
    int main(){
        srand(19260817); srand(rand()); srand(rand());
        scanf("%d", &n);
        for(int i = 1; i <= n; ++i)
           scanf("%d%d%d", &x[i], &y[i], &w[i]), sx += x[i], sy += y[i];
        nowx = sx * 1.0 / n; nowy = sy * 1.0 / n;
        while(clock() < 800) SA();
        printf("%.3lf %.3lf%", nowx, nowy);
        return 0;
    }
    
    
  • 相关阅读:
    QT中的列表容器
    QT中的Buttons
    QT中的常用控件
    [机房测试]弟娃
    CF1580C Train Maintenance
    [机房测试]数据恢复
    Sentry 监控
    Sentry 监控
    Sentry 监控
    Sentry 后端监控
  • 原文地址:https://www.cnblogs.com/Qihoo360/p/9718320.html
Copyright © 2011-2022 走看看