codeforces 2 C. Commentator problem(模拟退火)

题意:找一个点使这个点使这个点看三个圆的角度大小一样。

思路:模拟退火。初始化条件实在太难控制了。郁闷郁闷。


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <string>
#define LL long long
#define DB double
using namespace std;
bool zero(DB t){return -1e-6<t&&t<1e-6;}
struct cpoint{
    DB x,y;
    void get(){scanf("%lf%lf",&x,&y);}
};
DB ra,rb,rc;
cpoint a,b,c;
DB dist(cpoint a,cpoint b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
cpoint tar[109];
DB getrand()
{
    return (rand()*rand())%1000000/1000000.0*(rand()&1?-1:1);
}
DB ma(cpoint t)
{
    return max(fabs(t.x),fabs(t.y));
}
DB bin[109];
DB getbin(cpoint t)
{
    if(dist(t,a)<ra+1e-12||dist(t,b)<rb+1e-12||dist(t,c)<rc+1e-12) return 1e20;
    DB t1 = asin(ra/dist(t,a)),t2 =asin(rb/dist(t,b)),t3 = asin(rc/dist(t,c));
    return max(max(fabs(t1-t2),fabs(t1-t3)),fabs(t2-t3));
}
void init()
{
    for(int i=0;i<100;i++)
    {
        tar[i].x = getrand()*10;
        tar[i].y = getrand()*10;
    }
    for(int i=0;i<100;i++) bin[i] = getbin(tar[i]);
}
void solve()
{
    DB T=max(max(ma(a),ma(b)),ma(c))/5,delt=0.95,EPS = 1e-9;
    init();
    for(DB t=T;t>EPS;t*=delt)
    {
        cpoint tmp;
        for(int i=0;i<100;i++)
        {
            tmp.x = tar[i].x + t*getrand();
            tmp.y = tar[i].y + t*getrand();
            DB k = getbin(tmp);
            if(k<bin[i])
            {
                bin[i] = k;
                tar[i] = tmp;
            }
        }
    }
    for(int i=0;i<100;i++) 
    if((bin[i])<1e-5)
    {
        printf("%.5lf %.5lf\n",tar[i].x+EPS,tar[i].y+EPS);
        return;
    }
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    a.get();scanf("%lf",&ra);
    b.get();scanf("%lf",&rb);
    c.get();scanf("%lf",&rc);
    solve();
    return 0;
}

你可能感兴趣的:(模拟退火)