题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3007
这题和ZOJ1450是一样的,不过这个题目我换个解法
ZOJ1450我是用标准求最小点集覆盖求圆的方法来做的,速度很快
对于这一题目,我用的是模拟退火思想,每次像正确结果逼近
不过精度一点也不好控制,还有step也一点也不好控制,这些值都不能随便
取,要取特定意义的值才行!
恶心的是在ZOJ上就过不了!
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;
#define maxn 1500
#define MAX(a,b) (a>b?a:b)
#define eps 1e-20
struct point{
double x,y;
}po[maxn],cir;
int n;
double step;
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 find_max(point &a){
double ans=0,t;
for(int i=0;i<n;i++){
t=dis(po[i],a);
ans=MAX(ans,t);
}
return ans;
}
int solve(){
int i,j,k;
point temp,re;
double p,now;
step=find_max(po[0]);
cir=po[0];
while(step>eps){
temp=cir;
temp.x+=step;
re=temp;
now=find_max(temp);
temp=cir;
temp.y+=step;
p=find_max(temp);
if(p < now) now=p,re=temp;
temp=cir;
temp.y-=step;
p=find_max(temp);
if(p < now) now=p,re=temp;
temp=cir;
temp.x-=step;
p=find_max(temp);
if(p < now) now=p,re=temp;
step/=2;
cir=re;
}
printf("%.2lf %.2lf %.2lf\n",cir.x,cir.y,find_max(cir));
return 0;
}
int main(){
int i,j,k;
while(scanf("%d",&n),n){
for(i=0;i<n;i++)
scanf("%lf%lf",&po[i].x,&po[i].y);
if(n==1){
printf("%.2lf %.2lf %.2lf\n",po[0].x,po[0].y,0.0);
continue;
}
if(n==2){
printf("%.2lf %.2lf %.2lf\n",(po[0].x+po[1].x)/2,(po[0].y+po[1].y)/2,dis(po[0],po[1])/2);
continue;
}
solve();
}
return 0;
}