HDU - 6242 Geometry Problem (几何,思维,随机)

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;
}

全部评论

相关推荐

02-12 20:22
重庆大学 Java
字节暑期刚入职四天,因为是年前,所以很多正职都放假走了,也就没有给我分配mt,然后有一个老哥在我来的时候给我发了一个landing手册,然后还有关于部门业务的白皮书,还有一些业务代码。然后本人是java面的,进来第一次接触go语言&nbsp;前面几天熟悉了一下go的语法和go的框架,可以读但是还不太会写,然后业务白皮书也看的很头疼,包括landing手册里要了解的很多东西说实话我看文档真的快看死了,一个嵌套一个,问题是我还完全不知道咋用这个我了解的东西,还有就是那个项目代码,那个老哥喊我去写写单测,熟悉一下go的语法,但也进行的很困难(这是我第一段实习,之前都是springboot那一套,真不太熟悉这个)想问问大家的建议,就是我从现在开始到在开年回来之前应该做些什么,我目前就一个想法&nbsp;就是复现一个landing手册上的go框架小项目&nbsp;就是相当于帮自己锻炼锻炼怎么写go&nbsp;或者各位大佬有没有更好的锻炼go语法的建议还有就是大家都在说vibe&nbsp;coding,那我应该怎么锻炼自己使用ai的能力,感觉我除了给一些需求然后它给我生成代码,好像就没别的用法了,那些什么工作流、拆解、skill啥的都不知道从哪一个地方开始,包括我现在正在实习,不知道精力该怎么分配,去网上想找找关于agent开发的一些学习流程,说实话,众说纷纭,有的是从python开始打基础然后系统学那些rag&nbsp;prompt&nbsp;langchain&nbsp;mcp等等,有的是说直接找一个github上的ai项目然后反复问ai,我确实有点迷茫,恳求各位大佬能留下你们宝贵的建议,我一定认真反复深刻学习有一说一&nbsp;我觉得字节饭挺好吃的!
Jasonnnnnn...:直接把项目代码喂给AI然后让它帮你分析,如果组里已经有一些流程图总结的话最好,没有的话自己画一个 Go的话其实只要把基础语法搞明白就行了,项目里很多都是直接让ai帮你写好然后自己稍微改下,不用学的特别深 ai的话,可以自己写一些md文件来搞点小东西,但除非你打算转算法,否则不用把rag langchain学的特别深,了解下就行了
字节跳动公司福利 1371人发布
点赞 评论 收藏
分享
时间线:&nbsp;1.4-1.5:&nbsp;boss&nbsp;牛客&nbsp;官网&nbsp;实习僧海投了两天,&nbsp;感觉确实没啥招人的啊,&nbsp;心里凉了一半.1.6:&nbsp;中午快手约面,&nbsp;下午字节hr飞书私聊约面,&nbsp;当时想着第一次面大厂感觉三个过一个一面就已经赢了.1.7:&nbsp;下午&nbsp;3点大厂处女面,&nbsp;哈哈面试官是重邮红岩的直接保送;&nbsp;5点快手一面,&nbsp;我说这个是我的第二次大厂面试,&nbsp;面试官问要是拿到字节和快手选择哪个,&nbsp;我说昨天看了一晚上快手百分百选快手哈哈哈.&nbsp;晚上5.30字节约二面,&nbsp;快手约二面,&nbsp;小红书约一面.1.8:&nbsp;下午2点快手二面,&nbsp;聊天面体验非常好(当天电话确认入职时间);&nbsp;4点字节二面这次不是校友了,&nbsp;然后有一个CSS实现switch效果的忘记属性咋写了,&nbsp;感觉危了;&nbsp;7.30&nbsp;问字节hr是不是挂了;&nbsp;9点开始小红书一面,&nbsp;难死我了,&nbsp;但我还是笑着面完了,&nbsp;然后卸载了小红书,&nbsp;但是过了一会会小红书hr约二面,&nbsp;遂下回来了字节约三面.1.9:&nbsp;下午2点字节三面,&nbsp;依旧聊天+算法,&nbsp;自己太菜了有一个写错了,&nbsp;面完感觉又危了;&nbsp;5点面小红书20min结束(offer审批);5.30又去问字节hr是不是挂了,&nbsp;hr小姐姐说干嘛用一个句式,&nbsp;我说手写题又又又没写出来😂,&nbsp;2min后约hr面;8.30&nbsp;快手offer总结,&nbsp;自己运气好遇到了好公司好部门好面试官,&nbsp;字节剪映&nbsp;快手电商&nbsp;小红书支付的面试体验都非常好,&nbsp;不会的题会带你一步一步思考,&nbsp;流程也非常快全部都是当天推进,&nbsp;小红书是以分钟为单位推进.&nbsp;&nbsp;面经以及细节等我慢慢整理,&nbsp;&nbsp;以及保佑所有的审批不要出问题,&nbsp;我是真怕最后全过了0offer😂bg:&nbsp;重邮&nbsp;大数据&nbsp;蓝山工作室&nbsp;一段非大厂实习
独角仙梦境:这是真👻了
找实习记录
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务