1. 程式人生 > 實用技巧 >Aizu2972 All your base are belong to us

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;
}