zoukankan      html  css  js  c++  java
  • hdu6242 计算几何

    题意:给你n个点,要求找到一个点,和一个圆心,使得有n/2向上取整个点在圆上,一定有满足条件的点存在

    题解:既然一定有解,而且圆上有n/2向上取整个点,那么我们可以通过随机来找三个点来确定一个圆心,和半径,可以看出这三个点在圆上的概率是很大的,注意要特判点数为1,2,3,4的情况

    ps:一开始想的是随机两个点,后来发现这样两个点是直径的概率太小了,而且有可能根本不存在直径

    #include<bits/stdc++.h>
    #include<ext/rope>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define C 0.5772156649
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    
    using namespace std;
    using namespace __gnu_cxx;
    
    const double g=10.0,eps=1e-8;
    const int N=100000+10,maxn=400000+10,inf=0x3f3f3f;
    
    inline bool zero(double a)
    {
        return fabs(a)<eps;
    }
    struct point{
        double x,y;
        point(){};
        point(double _x,double _y)
        {
            x=_x;y=_y;
            if(zero(x))x=0.0;
            if(zero(y))y=0.0;
        }
    }p[N];
    int n;
    double R;
    double dis(point p1,point p2)
    {
        return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
    }
    double line(point p1,point p2,point p3)
    {
        return (p1.y-p2.y)*(p3.x-p2.x)==(p3.y-p2.y)*(p1.x-p2.x);
    }
    bool ok(point p0)
    {
        int ans=0;
        for(int i=0;i<n;i++)
        {
            if(zero(dis(p0,p[i])-R))
            {
                ans++;
            }
        }
        if(n&1)return ans>=(n/2+1);
        else return ans>=(n/2);
    }
    point getmid(point p1,point p2,point p3)
    {
        point pm={(p1.x+p2.x)/2,(p1.y+p2.y)/2};
        double a1=(p2.x-p1.x),b1=(p2.y-p1.y),c1=-pm.y*(p2.y-p1.y)-pm.x*(p2.x-p1.x);
        pm={(p1.x+p3.x)/2,(p1.y+p3.y)/2};
        double a2=(p3.x-p1.x),b2=(p3.y-p1.y),c2=-pm.y*(p3.y-p1.y)-pm.x*(p3.x-p1.x);
        pm={(c2*b1-c1*b2)/(a1*b2-a2*b1),(a2*c1-a1*c2)/(a1*b2-a2*b1)};
        R=dis(pm,p1);
        return pm;
    }
    int main()
    {
       /* ios::sync_with_stdio(false);
        cin.tie(0);*/
        srand(time(NULL));
        int t,cnt=0;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            for(int i=0;i<n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
            if(n==1)
            {
                point p0={0.0,0.0};
                printf("%.10f %.10f %.10f
    ",p0.x,p0.y,dis(p0,p[0]));
            }
            else if(n==2||n==3||n==4)
            {
                point p0={(p[1].x+p[0].x)/2,(p[1].y+p[0].y)/2};
                printf("%.10f %.10f %.10f
    ",p0.x,p0.y,dis(p0,p[0]));
            }
            else
            {
                while(1)
                {
                    int a=rand()%n,b=rand()%n,c=rand()%n;
                    if(a==b||b==c||a==c)continue;
                    if(line(p[a],p[b],p[c]))continue;
                    point p0=getmid(p[a],p[b],p[c]);
                    if(ok(p0))
                    {
                        printf("%.10f %.10f %.10f
    ",p0.x,p0.y,R);
                        break;
                    }
                }
            }
        }
        return 0;
    }
    /*******************
    
    ********************/
    View Code
  • 相关阅读:
    外键的缺陷
    laravel 关联模型
    n的阶乘末尾出现的次数
    JavaScript的self和this使用小结
    cocos2dx中的内存管理方式
    c++ 与 lua 简单交互参数介绍
    c++的单例模式及c++11对单例模式的优化
    cocos2dx帧动画
    cocos2dx中坐标系
    cocos2dx中替代goto的用法:do{}while(0)和CC_BREAK_IF
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/7825912.html
Copyright © 2011-2022 走看看