- P183's solution
P183's Solution
- 2025-9-4 22:00:08 @
参考模拟退火程序:
#include <bits/stdc++.h>
using namespace std;
long double w[6][1012];
inline long double dis(long double a,long double b,long double c,long double d)
{
return sqrtl((c-a)*(c-a)+(d-b)*(d-b));
}
inline bool blunt(long double a,long double b,long double c)
{
return (a*a+c*c<b*b||a*a+b*b<c*c);
}
inline long double height(long double a,long double b,long double c)
{
long double p=(a+b+c)/2;
return 2*sqrtl(p*(p-a)*(p-b)*(p-c))/a;
}
inline long double check(long double dx,long double dy,int p)
{
long double c=dis(dx,dy,w[0][p],w[1][p]);
long double b=dis(dx,dy,w[2][p],w[3][p]);
long double a=dis(w[0][p],w[1][p],w[2][p],w[3][p]);
long double res=min(b,c);
res=min(res,dis(dx,dy,w[4][p],w[5][p]));
if(!blunt(a,b,c)) res=min(res,height(a,b,c));
return res;
}
inline long double rd(long double m)
{
return rand()*1.0/RAND_MAX*m;
}
int go()
{
srand(time(0));
int n;
cin>>n;
long double s=0;
for(int i=1;i<=n;i++)
for(int j=0;j<=5;j++)
{
cin>>w[j][i];
s=max(s,w[j][i]);
}
long double S=pow(0.9999,-100000000.0/n),T=pow(0.9999,100000000.0/n);
long double bx=s/2,by=s/2,bz=1e9;
long double cx=s/2,cy=s/2,cz=1e9;
long double f=1;
while(S>T)
{
long double dx=bx+rd(s/10*f)-s/20*f;
long double dy=by+rd(s/10*f)-s/20*f;
long double dz=0;
for(int i=1;i<=n;i++)
dz=max(dz,check(dx,dy,i));
if(dz<bz) bx=dx,by=dy,bz=dz,cx=dx,cy=dy,cz=dz;
else if(rd(1)<exp((bz-dz)/S)) bx=dx,by=dy,bz=dz;
f-=1e-8;
S*=0.9999;
}
cout<<fixed<<setprecision(8)<<bx<<' '<<by<<' '<<bz<<endl;
return 0;
}
int main()
{
int T=1;
//cin>>T;
while(T--) go();
return 0;
}
参考答案():
5333.91419898 4918.20501141