• HDU


    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
    ",c.x+eps,c.y+eps,R);
    //        cout<<fixed<<setprecision(5)<<c.x+eps<<" "<<c.y+eps<<" "<<R<<endl;
        }
        return 0;
    }
    
    
    
    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    SQL Server-数据库架构和对象、定义数据完整性(二)
    SQL Server-语句类别、数据库范式、系统数据库组成(一)
    ASP.NET WebAPi之断点续传下载(下)
    ConcurrentDictionary线程不安全么,你难道没疑惑,你难道弄懂了么?
    ASP.NET WebAPi之断点续传下载(中)
    ASP.NET WebAPi之断点续传下载(上)
    ASP.NET WebAPi(selfhost)之文件同步或异步上传
    JSTL fn:contains()函数
    用jstl标签判断一个字符串是否包含了另一个字符串
    fn:replace()函数
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/11795049.html
Copyright © 2020-2023  润新知