Alice is interesting in computation geometry problem recently. She found a interesting problem and solved it easily. Now she will give this problem to you : 

You are given R. 

InputThe first line is the number of test cases. 

For each test case, the first line contains one positive number R. 
Sample Input

1
7
1 1
1 0
1 -1
0 1
-1 1
0 -1
-1 0

Sample Output

0 0 1

题意:给定N个点,求一个圆,使得圆上的点大于大于一半,保证有解。

思路:既然保证有解,我们就随机得到三角形,然后求外接圆取验证即可。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const double eps=1e-3;
const double pi=acos(-1.0);
struct point{
    double x,y;
    point(double a=0,double b=0):x(a),y(b){}
};
int dcmp(double x){ return fabs(x)<eps?0:(x<0?-1:1);}
point operator +(point A,point B) { return point(A.x+B.x,A.y+B.y);}
point operator -(point A,point B) { return point(A.x-B.x,A.y-B.y);}
point operator *(point A,double p){ return point(A.x*p,A.y*p);}
point operator /(point A,double p){ return point(A.x/p,A.y/p);}
point rotate(point A,double rad){
    return point(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));
}
bool operator ==(const point& a,const point& b) {
     return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}
double dot(point A,point B){ return A.x*B.x+A.y*B.y;}
double det(point A,point B){ return A.x*B.y-A.y*B.x;}
double dot(point O,point A,point B){ return dot(A-O,B-O);}
double det(point O,point A,point B){ return det(A-O,B-O);}
double length(point A){ return sqrt(dot(A,A));}
double angle(point A,point B){ return acos(dot(A,B)/length(A)/length(B));}
point jiaopoint(point p,point v,point q,point w)
{   //p+tv q+tw,点加向量表示直线,求直线交点
    point u=p-q;
    double t=det(w,u)/det(v,w);
    return p+v*t;
}
point GetCirPoint(point a,point b,point c)
{
    point p=(a+b)/2;    //ab中点
    point q=(a+c)/2;    //ac中点
    point v=rotate(b-a,pi/2.0),w=rotate(c-a,pi/2.0);   //中垂线的方向向量
    if (dcmp(length(det(v,w)))==0)    //平行
    {
        if(dcmp(length(a-b)+length(b-c)-length(a-c))==0) return (a+c)/2;
        if(dcmp(length(b-a)+length(a-c)-length(b-c))==0) return (b+c)/2;
        if(dcmp(length(a-c)+length(c-b)-length(a-b))==0) return (a+b)/2;
    }
    return jiaopoint(p,v,q,w);
}
const int maxn=100010;
point a[maxn]; int F[maxn];
bool check(point S,double R,int N){
    int num=0;
    rep(i,1,N){
        if(dcmp(length(a[i]-S)-R)==0) num++;
    }
    if(num>=(N+1)/2) return true; return false;
}
int main()
{
    int T,N,M;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&N);
        rep(i,1,N) scanf("%lf%lf",&a[i].x,&a[i].y);
        if(N==1) printf("%.6lf %.6lf %.6lf\n",a[1].x,a[1].y,0.0);
        else if(N==2) printf("%.6lf %.6lf %.6lf\n",(a[1].x+a[2].x)/2,(a[1].y+a[2].y)/2,length(a[1]-a[2])/2);
        else {
            while(true){
                rep(i,1,N) F[i]=i;
                random_shuffle(F+1,F+N+1);
                point S=GetCirPoint(a[F[1]],a[F[2]],a[F[3]]);
                double R=length(S-a[F[1]]);
                if(check(S,R,N)) {
                    printf("%.6lf %.6lf %.6lf\n",S.x,S.y,R);
                    break;
                }
            }
        }
    }
    return 0;
}

 

相关文章:

  • 2021-12-28
  • 2022-12-23
  • 2021-05-21
  • 2022-12-23
  • 2022-01-09
  • 2022-02-09
  • 2021-05-29
  • 2019-12-27
猜你喜欢
  • 2021-12-06
  • 2022-12-23
  • 2021-09-12
  • 2021-12-18
  • 2021-08-03
  • 2021-06-17
相关资源
相似解决方案