Groundhog Build Home HDU - 3932 【模拟退火】

题意:模拟退火就好,详细的代码注释在第一篇模拟退火里

#include<cstdio>
#include<vector>
#include<cmath>
#include<math.h>
#include<time.h>
#include<string>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<map>
#define PI acos(-1.0)
#define pb push_back
#define F first
#define S second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1005;
const int MOD=1e9+7;
const double eps=1e-10;
int sign(double x) {  //三态函数,减少精度问题
    return abs(x) < eps ? 0 : x < 0 ? -1 : 1;
}
struct Point{
    double x,y;
    Point(double x=0.0,double y=0.0):x(x),y(y){}
    Point operator +(const Point &rhs)const{
        return Point(x+rhs.x,y+rhs.y);
    }
    Point operator -(const Point &rhs)const{
        return Point(x-rhs.x,y-rhs.y);
    }
};
Point p[N];
double X,Y;
int n;
double dis(Point a,Point b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double cul(Point c){
    double mx=0;
    for(int i=0;i<n;i++)  mx=max(mx,dis(c,p[i]));
    return mx;
}
double myrand(){
    return rand()%10000/10000.0;
}
void SA(Point &c,double &r){
    c=Point(X/2,Y/2);
    double T=sqrt(X*X+Y*Y)/2;
    double E=cul(c);
    while(T>eps){
        Point next;
        double mn=1e20;
        for(int i=0;i<50;++i){
            double ang=2*PI*myrand();
            double x=c.x+cos(ang)*T;
            double y=c.y+sin(ang)*T;
            if(sign(x)<0)   x=0;
            if(sign(x-X)>0)   x=X;
            if(sign(y)<0)   y=0;
            if(sign(y-Y)>0)   y=Y;
            Point t(x,y);
            double tE=cul(t);
            if(tE<mn){
                mn=tE;
                next=t;
            }
        }
        if(sign(mn-E)<0 || exp(mn-E)/T<myrand()){
            E=mn;
            c=next;
        }
        T*=0.8;
    }
    r=E;
}
void mian(){
    for(int i=0;i<n;i++){
        double x,y;
        scanf("%lf%lf",&x,&y);
        p[i]=Point(x,y);
    }
    Point c;
    double r;
    SA(c,r);
    printf("(%.1f,%.1f).\n",c.x,c.y);
    printf("%.1f\n",r);
}
int main(void){
    srand(time(0));
    while(scanf("%lf%lf%d",&X,&Y,&n)==3){
        mian();
    }

    return 0;
}