• 星星还是树(模拟退火)


    题意

    在二维平面上,有(n)个点,找到距离这(n)个点距离之和最小的点。

    数据范围

    (1 leq n leq 100)
    (0 leq x_i, y_i leq 10000)

    思路

    模拟退火模板。这道题很容易证明是连续函数,因此可以使用模拟退火。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <ctime>
    
    using namespace std;
    
    typedef pair<double, double> pdd;
    
    const int N = 110;
    
    int n;
    pdd q[N];
    double ans = 1e8;
    
    double rand(double l, double r)
    {
        return (double)rand() / RAND_MAX * (r - l) + l;
    }
    
    double get_dist(pdd a, pdd b)
    {
        double distx = a.first - b.first;
        double disty = a.second - b.second;
        return sqrt(distx * distx + disty * disty);
    }
    
    double calc(pdd x)
    {
        double res = 0;
        for(int i = 1; i <= n; i ++) res += get_dist(x, q[i]);
        ans = min(res, ans);
        return res;
    }
    
    void simulate_anneal()
    {
        pdd cur = {rand(0, 10000), rand(0, 10000)};
        for(double t = 1e4; t > 1e-4; t *= 0.99) {
            pdd np = {rand(cur.first - t, cur.first + t), rand(cur.second - t, cur.second + t)};
            double dt = calc(np) - calc(cur);
            if(exp(-dt / t) > rand(0, 1)) cur = np;
        }
    }
    
    int main()
    {
        scanf("%d", &n);
        for(int i = 1; i <= n; i ++) scanf("%lf%lf", &q[i].first, &q[i].second);
        while((double)clock() / CLOCKS_PER_SEC < 0.8) simulate_anneal(); //卡时间的方法
        printf("%.0lf
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    vue $refs的用法
    .net 合并GridView中某列相同信息的行(方法1)
    vue 将编号转换成名字显示
    base64转图片的工具网站
    html +css + js 实现自定义模态框
    asp 弹窗效果
    vue 关于$emit的用法
    Git 合并分支
    asp 学习网站
    Tomcat部署方法
  • 原文地址:https://www.cnblogs.com/miraclepbc/p/14287474.html
Copyright © 2020-2023  润新知