Groundhog Build Home HDU - 3932(模拟退火算法)

Groundhog Build Home HDU - 3932

思路:

和前面一题类似,这个是求最大值最小化,还是随机30个点就行
// hdu 3932
#include<bits/stdc++.h>
using namespace std;
const double eps=1e-8;
const double inf=1e20;
const double PI=acos(-1.0);
const int maxn=1e5+3;
int times;
int sgn(double x)
{
    if(fabs(x)<eps) return 0;
    if(x<0) return -1;
    else return 1;
}
inline double square(double x) {return x*x;}
struct Point
{
    double x,y;
    Point()=default;
    Point(double x_, double y_):x(x_),y(y_){}
    void input(){scanf("%lf%lf",&x,&y);}
    void output(){printf("%.2lf %.2lf\n",x,y);}
    Point operator - (const Point &b) const
    {
        return Point(x-b.x,y-b.y);
    }
    bool operator==(Point b) const
    {
        return sgn(x-b.x)==0&&sgn(y-b.y)==0;
    }
    bool operator <(Point b) const
    {
        return sgn(x-b.x)==0?sgn(y-b.y)<0:x<b.x;
    }
    Point operator + (const Point &b) const
    {
        return Point(x+b.x,y+b.y);
    }
    double operator ^ (const Point &b) const
    {
        return x*b.y-y*b.x;
    }
    double operator * (const Point &b) const
    {
        return x*b.x+y*b.y;
    }
    Point operator/(const double &k)
    {
        return Point(x/k,y/k);
    }
    double len(){return hypot(x,y);}
    double len2(){return x*x+y*y;}
    double distance(Point b){return hypot(x-b.x,y-b.y);}

}p[maxn];
double X,Y;
int n;
double randNum(){       //rand()生成[0,32767),包装下生成[0,1)
    return rand()%10000/10000.0;
}
double maxDist(Point tmp)
{
    double ans=0;
    for(int i=0;i<n;i++)
    {
        ans=max(ans,p[i].distance(tmp));
    }
    return ans;
}
void Simulated(Point &ans,double step,double &res)
{
    times=30;
    Point nxt;
    double E=inf;
    double nE;
    while(step>eps)
    {
        Point tmp;
        nE=inf;
        for(int i=0;i<times;i++)
        {
            double angle=randNum()*2*PI;
            tmp.x=ans.x+step*cos(angle);
            tmp.y=ans.y+step*sin(angle);
            double tE=maxDist(tmp);
            if(nE>tE)
            {
                nE=tE;
                nxt=tmp;
            }
        }
        if(E>nE)
        {
            E=nE;
            ans=nxt;
            res=E;
        }
        step*=0.9;
    }
}
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    while(scanf("%lf%lf%d",&X,&Y,&n)!=EOF)
    {
        for(int i=0;i<n;i++)
        {
            p[i].input();
        }
        double step=Point(0,0).distance(Point(X,Y))/2.0;
        Point ans=Point(X/2.0,Y/2.0);
        double res=inf;
        Simulated(ans,step,res);
        printf("(%.1lf,%.1lf).\n",ans.x,ans.y);
        printf("%.1lf\n",res);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40774175/article/details/82498436