HFUT 1288 银河系5A风景区[安徽省第三届省赛]

来源:互联网 发布:算法导论电子书 编辑:程序博客网 时间:2024/04/27 23:09

转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents           by---cxlove

题目:给出球上4个点,求球心坐标

http://acm.hfut.edu.cn/OnlineJudge/

赤果果的是模拟退火啊。。。

当时完全不知道,果断YY了一下之后只能放弃。

对于每一个点,我们计算一下与目标圆心的误差。方差???

随机一点,然后设定一个初始步长,每一次随机30个方向走出去,如果比当前位置更优,则更新

直到步长达到要求的精度。

这题给的时限有3s,范围是1000,貌似精度要求还是很高的,每次step减小0.05倍都不能过。

最终1s+过了,效率不高。

#include<iostream>#include<fstream>#include<iomanip>#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<cmath>#include<set>#include<map>#include<queue>#include<stack>#include<string>#include<vector>#include<sstream>#include<ctime>#include<cassert>#define LL long long#define eps 1e-8#define inf 999999.0#define zero(a) fabs(a)<eps#define N 20#define pi acos(-1.0)using namespace std;struct Point{    double x,y,z;    bool check(){        if(fabs(x)<500+eps&&fabs(z)<500+eps&&fabs(y)<500+eps)              return true;        return false;    }}p[4],cur,central;double dist(Point p1,Point p2){    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)+(p1.z-p2.z)*(p1.z-p2.z));}//当前状态与目标态的误差double Get_Diff(Point cen){    double diff=0,sum=0,dis[4];    for(int i=0;i<4;i++){        dis[i]=dist(cen,p[i]);        sum+=dis[i];    }    sum/=4;    for(int i=0;i<4;i++)        diff+=(dis[i]-sum)*(dis[i]-sum);    return diff;}int main(){    int t,cas=0;    scanf("%d",&t);    while(t--){        for(int i=0;i<4;i++)            scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z);        central.x=central.y=central.z=0;        //步长初始1000,初始位置0,0,0        double step=1000,best=Get_Diff(central);        while(step>0.001){            for(int i=0;i<30;i++){                //随机一个方向                double a=(rand()%30000+1)/30000.0*pi*2;                double b=(rand()%30000+1)/30000.0*pi*2;                cur.x=central.x+step*sin(a)*cos(b);                cur.y=central.y+step*sin(a)*sin(b);                cur.z=central.z+step*cos(a);                if(!cur.check()) continue;                double tmp=Get_Diff(cur);                if(tmp+eps<best){                     best=tmp;                    central=cur;                }            }            step*=0.95;        }        printf("Case #%d: %.1f %.1f %.1f\n",++cas,central.x,central.y,central.z);    }    return 0;}

原创粉丝点击