zoukankan      html  css  js  c++  java
  • 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/ 希望所写的文章对您有帮助。
  • 相关阅读:
    微信朋友圈怎么发文字?如何只发文字和表情?
    微信将推指纹支付 "指付通"会与Touch ID整合吗
    微信公众平台上传图片很卡 微信整合京东的关系?
    微信公众平台可以修改名称吗?微信认证时可以改名!
    怎样制作漂亮的微信二维码?用在线二维码生成器!
    微信网页版APP
    织梦channelid是什么?dede channel typeid有什么区别
    微信消息如何添加文字链接?【微信公众平台技巧】
    为什么在有些文章末尾加一张收录截图?
    5步教你设置微信自定义菜单【微信公众平台技巧】
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/11795049.html
Copyright © 2011-2022 走看看