Aizu2972 All your base are belong to us
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2972
模拟退火
首先看一下题,以为总部必须在某个点上
仔细一看,居然可以在任意点上
咋办,枚举?
我太菜,没想到三分套三分(其实不会)
只好模拟退火,样例第\(5\)位就炸了,时间复杂度也很慌
结果就过了??
\(C++ Code:\)
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#define dis(p,q,s,t) (sqrt((p-s)*(p-s)+(q-t)*(q-t)))
#define N 405
#define db double
using namespace std;
int n,k;
struct node
{
db x,y;
}a[N];
db g[N],sx,sy,ans;
db Judge(db x,db y)
{
for (int i=1;i<=n;i++)
g[i]=dis(a[i].x,a[i].y,x,y);
sort(g+1,g+n+1);
db ans=0;
for (int i=n;i>=n-k+1;i--)
ans+=g[i];
return ans;
}
void SA()
{
db tem=2477,jw=0.999546;
while (tem>1e-12)
{
db xx=sx+(rand()*2-RAND_MAX)*tem;
db yy=sy+(rand()*2-RAND_MAX)*tem;
db d=Judge(xx,yy);
db del=d-ans;
if (del<0)
{
sx=xx;
sy=yy;
ans=d;
} else
if (exp(-del/tem)*RAND_MAX>rand())
{
sx=xx;
sy=yy;
}
tem*=jw;
}
}
int main()
{
srand(242);
scanf("%d%d",&n,&k);
for (int i=1;i<=n;i++)
scanf("%lf%lf",&a[i].x,&a[i].y),sx+=a[i].x,sy+=a[i].y;
sx/=(double)n,sy/=(double)n;
ans=Judge(sx,sy);
SA();SA();
printf("%.5lf\n",ans);
return 0;
}