【三维三分/模拟退火】D - Country Meow 2018icpc南京

题面

https://vjudge.net/problem/Gym-101981A

题意

给n个在三维坐标上的点(x,y,z),在空间中假设有一个点a,求每个点到点a的距离的最大值,而题目要使得这个最大值最小

思路

分析可得,对于每一维,另外两维固定后,另一维和答案的关系呈一个凹函数,所以可以使用三分套三分套三分的方法,使用递归来实现

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const double pi=acos(-1);
const double feps=1e-8;
const int maxn=6000;
struct point
{
    double x[5];
}p[110];
int n;
double cal(struct point qaq)
{
    double res=0;
    for(int i=1;i<=n;i++)
    {
        double tmp=0;
        for(int j=1;j<=3;j++)
            tmp+=(qaq.x[j]-p[i].x[j])*(qaq.x[j]-p[i].x[j]);
        res=max(res,sqrt(tmp));
    }
    return res;
}
struct point Cal(int cnt,struct point now)
{
    if(cnt>=4) return now;
    double l=-100000,r=100000;
    struct point ans,tmpl,tmpr,ansl,ansr;
    tmpl=now;tmpr=now;
    while(feps<r-l)
    {
        double ll=(2*l+r)/3,rr=(l+2*r)/3;
        tmpl.x[cnt]=ll;tmpr.x[cnt]=rr;
        ansl=Cal(cnt+1,tmpl);
        ansr=Cal(cnt+1,tmpr);
        if(cal(ansl)>cal(ansr))
        {
            l=ll;
            ans=ansl;
        }
        else
        {
            r=rr;
            ans=ansr;
        }
    }
    return ans;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=3;j++)
         scanf("%lf",&p[i].x[j]);
    struct point ans;
    for(int i=1;i<=3;i++) ans.x[i]=0;
    printf("%.15f\n",cal(Cal(1,ans)));
    return 0;
}

模拟退火

等我学了吧…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值