hdu 6242 Geometry Problem(随机化+三点求外接圆)

来源:互联网 发布:怎么管理mac下面的图标 编辑:程序博客网 时间:2024/06/18 09:00

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

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).

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

Output
For each test case, output a single line with three real numbers XP,YP,R, where (XP,YP) is the coordinate of required point P. Three real numbers you output should satisfy 0≤|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 R if it is within an absolute error of 10−3 of 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个点,让你找出一个圆,满足至少有一半的点(向上取整)满足这些点在圆上,保证有解,答案如果有多种任意输出一种即可。

思路:每次随机三个点,求出外接圆,然后判断是否满足条件。注意这三个点不能相同且不能再同一直线上。如果n小于4的话要特殊考虑下.还有就是答案不能大于1e9
代码如下

#include<cstdio>  #include<cstdlib>  #include<cmath>  #include<iostream>using namespace std;const int maxn =1e5+5;const double eps=1e-6;struct Point {    double x,y;};Point s[maxn];int judge(int a,int b,int c){    if(a==b||a==c||b==c)        return 1;    if((s[b].x-s[a].x)*(s[c].y-s[a].y)==(s[c].x-s[a].x)*(s[b].y-s[a].y))        return 1;    return 0;}int main() {    int T;    int n;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        for(int i=1;i<=n;i++)        {            scanf("%lf%lf",&s[i].x,&s[i].y);        }        if(n==1)        {            printf("%lf %lf 1.00000\n",s[1].x+1,s[1].y);            continue;        }        else if(n<=4)        {            double r=sqrt((s[1].x-s[2].x)*(s[1].x-s[2].x)+(s[1].y-s[2].y)*(s[1].y-s[2].y))/2;            printf("%lf %lf %lf\n",(s[1].x+s[2].x)/2,(s[1].y+s[2].y)/2,r);            continue;        }        double x,y,r;        while(1)          {              int a = rand()%n+1;              int b = rand()%n+1;              int c = rand()%n+1;              if(judge(a, b, c))                  continue;              //三点求圆心坐标公式                x = (s[a].x*s[a].x-s[b].y*s[b].y-s[b].x*s[b].x+s[a].y*s[a].y)*(s[a].y-s[c].y)-(s[a].x*s[a].x-s[c].y*s[c].y-s[c].x*s[c].x+s[a].y*s[a].y)*(s[a].y-s[b].y);              x /= 2*(s[a].y-s[c].y)*(s[a].x-s[b].x)-2*(s[a].y-s[b].y)*(s[a].x-s[c].x);              y = (s[a].x*s[a].x-s[b].y*s[b].y-s[b].x*s[b].x+s[a].y*s[a].y)*(s[a].x-s[c].x)-(s[a].x*s[a].x-s[c].y*s[c].y-s[c].x*s[c].x+s[a].y*s[a].y)*(s[a].x-s[b].x);              y /= 2*(s[a].y-s[b].y)*(s[a].x-s[c].x)-2*(s[a].y-s[c].y)*(s[a].x-s[b].x);              r = sqrt((s[a].x-x)*(s[a].x-x)+(s[a].y-y)*(s[a].y-y));              int sum = 0;              for(int i=1;i<=n;i++)              {                  if(fabs(sqrt((s[i].x-x)*(s[i].x-x)+(s[i].y-y)*(s[i].y-y))-r)<1e-6)                      sum++;              }              if(sum>=(n+1)/2&&fabs(x)<1e9&&fabs(y)<1e9&&fabs(r)<1e9)                  break;          }          printf("%lf %lf %lf\n", x, y, r);      }      return 0;}
阅读全文
0 0
原创粉丝点击