bzoj2823: [AHOI2012]信号塔

传送门

一个最小圆覆盖的模板。

之前一直没懂三点求圆心的那段代码,orz汪神

 

//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#define eps 1e-6
const int N=1000007; 
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
typedef long long LL;
typedef double db;
using namespace std;
int n;
db r;

template<typename T>void read(T &x)  {
    char ch=getchar(); x=0; T f=1;
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') f=-1,ch=getchar();
    for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}

struct pt {
    db x,y;
    pt(){}
    pt(db x,db y):x(x),y(y){}
}p[N],C;

pt operator + (const pt&A,const pt&B) { return pt(A.x+B.x,A.y+B.y); }
pt operator - (const pt&A,const pt&B) { return pt(A.x-B.x,A.y-B.y); }
pt operator * (const pt&A,const db&B) { return pt(A.x*B,A.y*B); }
pt operator / (const pt&A,const db&B) { return pt(A.x/B,A.y/B); }
db dot(const pt&A,const pt&B) { return A.x*B.x+A.y*B.y; }
db cross(const pt&A,const pt&B) { return A.x*B.y-A.y*B.x; }
db length(pt A) { return dot(A,A); }
int dcmp(db a) { return fabs(a)<=eps?0:(a>0?1:-1); }
bool operator < (const pt &A,const pt&B) { return dcmp(A.x-B.x)<0||(dcmp(A.x-B.x)==0&&dcmp(A.y-B.y)<0);}

pt get_circle_center(pt A,pt B,pt C) {
    pt rs;
    db a1=B.x-A.x,a2=C.x-A.x;
    db b1=B.y-A.y,b2=C.y-A.y;
    db c1=(a1*a1+b1*b1)/2.0;
    db c2=(a2*a2+b2*b2)/2.0;
    db d=a1*b2-a2*b1;
    rs.x=A.x+(c1*b2-c2*b1)/d;
    rs.y=A.y+(c2*a1-c1*a2)/d;
    return rs;
}

void min_circle_cover(int n,pt p[],pt &c,db &r) {
    random_shuffle(p+1,p+n+1);
    c=p[1]; r=0;
    For(i,2,n) if(dcmp(length(p[i]-c)-r)>0) {
        c=p[i];
        r=0;
        For(j,1,i-1) if(dcmp(length(p[j]-c)-r)>0){
            c=(p[i]+p[j])/2;
            r=length(p[i]-c);
            For(k,1,j-1) if(dcmp(length(p[k]-c)-r)>0){
                c=get_circle_center(p[i],p[j],p[k]);
                r=length(p[i]-c);
            }
        }
    }
}

int main() {
    srand(998244353);
    read(n);
    For(i,1,n) scanf("%lf%lf",&p[i].x,&p[i].y);
    min_circle_cover(n,p,C,r);
    printf("%.2lf %.2lf %.2lf\n",C.x,C.y,sqrt(r));
    return 0;
}
/*
5 
1.200 1.200 
2.400 2.400 
3.800 4.500 
2.500 3.100 
3.900 1.300 
*/
View Code

 

posted @ 2018-03-24 09:12  啊宸  阅读(222)  评论(0编辑  收藏  举报