HDU - 6242:Geometry Problem(随机+几何)

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.

InputThe 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. 
OutputFor 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个点,求一个圆,使得圆上的点大于大于一半,保证有解。

思路:既然保证有解,我们就随机得到三角形,然后求外接圆取验证即可。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const double eps=1e-3;
const double pi=acos(-1.0);
struct point{
    double x,y;
    point(double a=0,double b=0):x(a),y(b){}
};
int dcmp(double x){ return fabs(x)<eps?0:(x<0?-1:1);}
point operator +(point A,point B) { return point(A.x+B.x,A.y+B.y);}
point operator -(point A,point B) { return point(A.x-B.x,A.y-B.y);}
point operator *(point A,double p){ return point(A.x*p,A.y*p);}
point operator /(point A,double p){ return point(A.x/p,A.y/p);}
point rotate(point A,double rad){
    return point(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));
}
bool operator ==(const point& a,const point& b) {
     return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}
double dot(point A,point B){ return A.x*B.x+A.y*B.y;}
double det(point A,point B){ return A.x*B.y-A.y*B.x;}
double dot(point O,point A,point B){ return dot(A-O,B-O);}
double det(point O,point A,point B){ return det(A-O,B-O);}
double length(point A){ return sqrt(dot(A,A));}
double angle(point A,point B){ return acos(dot(A,B)/length(A)/length(B));}
point jiaopoint(point p,point v,point q,point w)
{   //p+tv q+tw,点加向量表示直线,求直线交点
    point u=p-q;
    double t=det(w,u)/det(v,w);
    return p+v*t;
}
point GetCirPoint(point a,point b,point c)
{
    point p=(a+b)/2;    //ab中点
    point q=(a+c)/2;    //ac中点
    point v=rotate(b-a,pi/2.0),w=rotate(c-a,pi/2.0);   //中垂线的方向向量
    if (dcmp(length(det(v,w)))==0)    //平行
    {
        if(dcmp(length(a-b)+length(b-c)-length(a-c))==0) return (a+c)/2;
        if(dcmp(length(b-a)+length(a-c)-length(b-c))==0) return (b+c)/2;
        if(dcmp(length(a-c)+length(c-b)-length(a-b))==0) return (a+b)/2;
    }
    return jiaopoint(p,v,q,w);
}
const int maxn=100010;
point a[maxn]; int F[maxn];
bool check(point S,double R,int N){
    int num=0;
    rep(i,1,N){
        if(dcmp(length(a[i]-S)-R)==0) num++;
    }
    if(num>=(N+1)/2) return true; return false;
}
int main()
{
    int T,N,M;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&N);
        rep(i,1,N) scanf("%lf%lf",&a[i].x,&a[i].y);
        if(N==1) printf("%.6lf %.6lf %.6lf\n",a[1].x,a[1].y,0.0);
        else if(N==2) printf("%.6lf %.6lf %.6lf\n",(a[1].x+a[2].x)/2,(a[1].y+a[2].y)/2,length(a[1]-a[2])/2);
        else {
            while(true){
                rep(i,1,N) F[i]=i;
                random_shuffle(F+1,F+N+1);
                point S=GetCirPoint(a[F[1]],a[F[2]],a[F[3]]);
                double R=length(S-a[F[1]]);
                if(check(S,R,N)) {
                    printf("%.6lf %.6lf %.6lf\n",S.x,S.y,R);
                    break;
                }
            }
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/hua-dong/p/9696852.html

时间: 2024-10-05 23:16:28

HDU - 6242:Geometry Problem(随机+几何)的相关文章

HDU 6242 Geometry Problem(计算几何 + 随机化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6242 思路:当 n == 1 时 任取一点 p 作为圆心即可. n >= 2 && n < 5 时 此时有可能出现所有点共线,所以取任意俩点间中点作为圆的圆心. n >= 5 保证了有解.所以不可能有所有点共线的情况,随机取三个点在正解圆上的概率是 1/8,还是蛮大的.... 外学了下随机算法的写法....时间种子 time(0)要强制转成int,不然会WA,不造为啥....

hdu 1086 You can Solve a Geometry Problem too (几何)

You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6932    Accepted Submission(s): 3350 Problem Description Many geometry(几何)problems were designed in the ACM/I

HDU 1086:You can Solve a Geometry Problem too

You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6997    Accepted Submission(s): 3385 Problem Description Many geometry(几何)problems were designed in the ACM/

hdu 1086 You can Solve a Geometry Problem too(求线段相交点个数 模板)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1086 ---------------------------------------------------------------------------------------------------------------------------------------------------------- 欢迎光临天资小屋:http://user.qzone.qq.com/593830943

You can Solve a Geometry Problem too (hdu1086)几何,判断两线段相交

You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6837 Accepted Submission(s): 3303 Problem Description Many geometry(几何)problems were designed in the ACM/ICPC. A

HDU 1086 You can Solve a Geometry Problem too(判断线段相交)

题目地址:HDU 1086 就这么一道仅仅判断线段相交的题目写了2k多B的代码..是不是有点浪费...但是我觉得似乎哪里也优化不了了.... 判断线段相交就是利用的叉积.假如现在两条线段分别是L1和L2,先求L1和L2两个端点与L1的某个端点的向量的叉积,如果这两个的叉积的乘积小于0的话,说明L1在是在L2两个端点之间的,但此时并不保证一定相交.此时需要用同样的方法去判断L2是否在L1的两个端点之间,如果L2也在L1的两个端点之间的话,那就足以说明L1与L2相交.但是这题还需要判断是否端点也相交

(hdu 7.1.2)You can Solve a Geometry Problem too(求n条线段中,线段两两相交的数量)

题目: You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 145 Accepted Submission(s): 100   Problem Description Many geometry(几何)problems were designed in the ACM/IC

You can Solve a Geometry Problem too(线段求交)

http://acm.hdu.edu.cn/showproblem.php?pid=1086 You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8861    Accepted Submission(s): 4317 Problem Description Many

HDOJ1086-You can Solve a Geometry Problem too(线段相交)

Problem Description Many geometry(几何)problems were designed in the ACM/ICPC. And now, I also prepare a geometry problem for this final exam. According to the experience of many ACMers, geometry problems are always much trouble, but this problem is ve