<span>HDU - 6242 Geometry Problem (几何,思维,随机)</span>

Geometry Problem

HDU - 6242

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 NN distinct points (Xi,Yi)(Xi,Yi) on the two-dimensional plane. Your task is to find a point PP and a real number RR, such that for at least ⌈N2⌉⌈N2⌉ given points, their distance to point PP is equal to RR.

Input

The first line is the number of test cases.

For each test case, the first line contains one positive number N(1≤N≤105)N(1≤N≤105).

The following NN lines describe the points. Each line contains two real numbers XiXiand YiYi (0≤|Xi|,|Yi|≤103)(0≤|Xi|,|Yi|≤103) indicating one give point. It's guaranteed that NN points are distinct.

Output

For each test case, output a single line with three real numbers XP,YP,RXP,YP,R, where (XP,YP)(XP,YP) is the coordinate of required point PP. Three real numbers you output should satisfy 0≤|XP|,|YP|,R≤1090≤|XP|,|YP|,R≤109.

It is guaranteed that there exists at least one solution satisfying all conditions. And if there are different solutions, print any one of them. The judge will regard two point's distance as RR if it is within an absolute error of 10−310−3 of RR.

Sample Input

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

Sample Output

0 0 1

题意:

给n个互补相同的二维坐标点,保证可以找到一个点\(p(x,y)\),满足存在\(ceil(n/2)\) 个点和这个点p的距离相同。

思路:

当n=1时,p可以为任意一点

\(2<=n<=4\) 时,取任意两点的中点即可,

当n>=5 时,

我们随机3个互补相同的点,并找到以这3个点确定的圆的圆心以及半径R,然后计算有多少个点和这个圆心的距离为R,如果个数*2>=n,就说明该圆心就是要找的点,半径就是距离。

为什么这样可以?

因为保证一定存在解,那么一定有至少\(ceil(n/2)\) 个点在同一个圆上,那么找到3个点都在这个圆上的概率大概就是\((1/2)^3\) 那么期望大概就是8次就可以确定出圆心。

ac代码

#include<bits/stdc++.h>
#include<ctime>
using namespace std;
typedef long long ll;
typedef double ld;
const ld eps = 1e-6;

int sgn(ld x)
{
    if(fabs(x)<eps)
        return 0;
    if(x<0)
        return -1;
    else
    {
        return 1;
    }
}
struct point
{
    ld x,y;
    point(){}
    point(ld _x,ld _y)
    {
        x=_x;
        y=_y;
    }
    point operator - (const point &b) const
    {
        return point(x-b.x,y-b.y);
    }
    ld operator ^ (const point &b) const
    {
        return x*b.y-y*b.x;
    }
    ld operator * (const point &b) const
    {
        return x*b.x+y*b.y;
    }

};
point getpoint(point a,point b,point c,point d)
{
    point res;
    ld a1,b1,c1,a2,b2,c2;
    a1=a.y-b.y,b1=b.x-a.x,c1=a.x*b.y-b.x*a.y;
    a2=c.y-d.y,b2=d.x-c.x,c2=c.x*d.y-d.x*c.y;
    res.x=(b1*c2-b2*c1)/(a1*b2-a2*b1);
    res.y=-(a1*c2-a2*c1)/(a1*b2-a2*b1);
    return res;
}
struct line
{
    point s,e;
    line(){}
    line(point _s,point _e)
    {
        s=_s;
        e=_e;
    }
    pair<int,point> operator & (const line &b)const
    {
        point res=s;
        if(sgn((s-e)^(b.s-b.e))==0)
        {
            if(sgn((s-b.e)^(b.s-b.e))==0)
            {
                return make_pair(0,res);
            }else{
                return make_pair(1,res);
            }
        }
        res = getpoint(s,e,b.s,b.e);
        return make_pair(2,res);
    }
};

int t;
int n;
point a[100010];
ld R;
line l1,l2;
ld base=2e9;
line getline_(point aa,point bb)
{
    ld xc=bb.x-aa.x;
    ld yc=bb.y-aa.y;
    if(sgn(yc)==0)
    {
        return line(point(bb.x,base),point(bb.x,-base));
    }else
    {
        ld k=-1*xc/yc;
        point mid=point((aa.x+bb.x)*0.5,(aa.y+bb.y)*0.5);
        return line(point(mid.x+base,mid.y+base*k),point(mid.x-base,mid.y-base*k));
    }
}
ld getdis(point aa,point bb)
{
    return sqrt((aa.x-bb.x)*(aa.x-bb.x)+(aa.y-bb.y)*(aa.y-bb.y));
}
point c;
bool check(point aa,point bb,point cc)
{
    l1=getline_(aa,bb);
    l2=getline_(bb,cc);
    pair<int,point> res=l1&l2;
    if(res.first!=2)
    {
        return 0;
    }else if(res.first==2)
    {
        c=res.second;
        R=getdis(c,aa);
        int cnt=0;
        for(int i=1;i<=n;++i)
        {
            if(sgn(fabs(getdis(c,a[i]))-R)==0)
            {
//                cout<<getdis(c,a[i])<<endl;
                cnt++;
            }
        }
//        cout<<" cnt "<<" "<<cnt<<endl;
        return cnt*2>=n;
    }
}
//#define mp make_pair
//
//map<pair<int,pair<int,int> >,bool > vis;
int main()
{
//    ios::sync_with_stdio(false);
//    cin>>t;
    int x,y;
    scanf("%d",&t);
    while(t--)
    {
//        vis.clear();
        std::mt19937 rnd(time(NULL));
//        cin>>n;
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {
            scanf("%lf %lf",&a[i].x,&a[i].y);
//            cin>>a[i].x>>a[i].y;
        }
        if(n==1)
        {
            c.x=0;
            c.y=0;
            R=getdis(c,a[1]);
        }else if(n<=4)
        {
            c=point((a[1].x+a[2].x)*0.5,(a[1].y+a[2].y)*0.5);
            R=getdis(c,a[1]);
        }else
        {
            while(1)
            {
                int id1,id2,id3;
                id1=rnd()%n+1;
                do
                {
                    id2=rnd()%n+1;
                }while(id2==id1);
                do
                {
                    id3=rnd()%n+1;
                }while(id3==id1||id3==id2);
    //            cout<<id1<<" "<<id2<<" "<<id3<<endl;
                if(check(a[id1],a[id2],a[id3]))
                {
                    break;
                }
            }
        }
        printf("%.5f %.5f %.5f\n",c.x+eps,c.y+eps,R);
//        cout<<fixed<<setprecision(5)<<c.x+eps<<" "<<c.y+eps<<" "<<R<<endl;
    }
    return 0;
}


全部评论

相关推荐

牛客965593684号:假的,字节hr都是不会找你内推的,直接就是同学我们约个面试?他们有权限直接捞你的。
点赞 评论 收藏
分享
下北泽:都是校友,还是同届,我就说直白点,不委婉了,我相信你应该也不是个玻璃心,首先你觉得一个双非的绩点写简历上有用吗?班长职务有用吗?ccf有用吗?企业会关心你高数满分与否吗?第二,第一个项目实在太烂,一眼就能看出是外卖,还是毫无包装的外卖,使用JWT来鉴权,把热点数据放进Redis这两个点居然还能写进简历里,说难听点这两个东西都是学个几十分钟,调用个API就能完成的事情,在双非一本的条件下,这种项目你觉得能拿出手吗,第二个项目你写的东西和你的求职方向有任何的匹配吗?第三,计设那一块毫无价值,如果想突出自己会前端,直接写入专业技能不行吗,最后,专业技能里像深入理解JVM底层原理这种你觉得这句话你自己真的能匹配吗?都是校友加上同届,我措辞直接,但希望能点出你的问题,想进大厂还得继续沉淀项目和学习
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务