zoukankan      html  css  js  c++  java
  • Machining Disc Rotors Gym

    Machining Disc Rotors Gym - 101955L

    题意:有一个圆心为((0,0))的大圆被(n)个互不相交的圆切割(下图阴影部分为割掉的面积)。保证(n)个圆中不会有某个包含整个大圆的情况。问切割后大圆剩余部分的直径(多边形上两点最远距离)。

    题解:显然剩余部分的直径是以下两种之一:

    • 原本大圆的直径。
    • 两个交点的距离。

    如何判断是否存在直径呢?我们可以把每一个交点关于圆心作对称点,如果有一个对称点都不在(n)个圆内,说明这个点与对称点构成了一条没有被切掉的直径。若没有则是两交点之间的最大距离。

    #include <bits/stdc++.h>
    #define fopi freopen("in.txt", "r", stdin)
    #define fopo freopen("out.txt", "w", stdout)
    using namespace std;
    typedef long long LL;
    const int inf = 0x3f3f3f3f;
    const double eps = 1e-10;
    const int maxn = 1000 + 10;
    
    struct Point{
        double x,y;
        Point(double x=0,double y=0):x(x),y(y){}
    };
    typedef Point Vector;
    Vector operator + (Vector A,Vector B){
        return Vector(A.x+B.x,A.y+B.y);
    }
    Vector operator - (Point A,Point B){
        return Vector(A.x-B.x,A.y-B.y);
    }
    Vector operator * (Point A,double p){
        return Vector(A.x*p,A.y*p);
    }
    
    int dcmp(double x) { return fabs(x) < eps ? 0 : (x < 0 ? -1 : 1); }
    bool operator == (const Point& a,const Point& b){
        return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
    }
    
    double Dot(Vector A,Vector B){
        return A.x*B.x+A.y*B.y;
    }
    double Length(Vector A){
        return sqrt(Dot(A,A));
    }
    
    struct Circle{
        Point c;
        double r;
        Circle() {}
        Circle(Point c,double r):c(c),r(r){}
        Point point(double a){
            return Point(c.x+cos(a)*r,c.y+sin(a)*r);
        }
    };
    
    double angle(Vector v) {
        return atan2(v.y, v.x);
    }
    
    //Circle and Circle intersection
    int CCIntersection(Circle C1,Circle C2,vector<Point>& sol){
        double d=Length(C1.c-C2.c);
        if(dcmp(d)==0){
            if(dcmp(C1.r-C2.r)==0)return -1;
            return 0;
        }
        if(dcmp(C1.r+C2.r-d)<0)return 0;
        if(dcmp(fabs(C1.r-C2.r)-d)>0)return 0;
    
        double a=angle(C2.c-C1.c);
        double da=acos((C1.r*C1.r+d*d-C2.r*C2.r)/(2*C1.r*d));
    
        Point p1=C1.point(a-da),p2=C1.point(a+da);
    
        sol.push_back(p1);
        if(p1==p2)return 1;
        sol.push_back(p2);
        return 2;
    }
    
    bool PinC(Point p, Circle c) { //Point in Circle
        double dist = Length(p-c.c);
        return dcmp(dist-c.r) < 0;
    }
    
    
    int T, n;
    double r;
    Circle a[maxn];
    vector<Point> sect, k;
    
    bool check() {
        if (sect.empty()) return true;
        for (auto p : sect) {
            bool flag = true;
            Point p1 = {-p.x, -p.y};
            for (int i = 1; i <= n; i++)
                if (PinC(p1, a[i])) {
                    flag = false;
                    break;
                }
            if (flag) return true;
        }
        return false;
     }
    
    int main() {
        scanf("%d", &T);
        for (int ca = 1; ca <= T; ca++) {
            sect.clear();
            scanf("%d%lf", &n, &r);
            Circle mid = {{0,0}, r};
            Point p1, p2;
            for (int i = 1; i <= n; i++) {
                int x, y, z;
                scanf("%d%d%d", &x, &y, &z);
                a[i] = {{x, y}, z};
                CCIntersection(a[i], mid, sect);
            }
            double ans = 0, tmp;
            for (int i = 0; i < sect.size(); i++)
                for (int j = i+1; j < sect.size(); j++) {
                    if ((tmp = Length(sect[i]-sect[j])) > ans) ans = tmp;
                }
            printf("Case #%d: %.15f
    ", ca, check() ? 2*r : ans);
        }
    }
    
  • 相关阅读:
    一百二十三:CMS系统之登录功能
    一百二十二:CMS系统之页面抽离和登录页面
    一百二十一:CMS系统之注册后跳转到上一个页面
    一百二十:CMS系统之注册功能前后端逻辑
    Python基础语法习题二
    编程语言分类和Python解释器介绍
    VS Code设置中文和配置Python环境
    Windows10系统下安装python2和python3双版本
    Python下载与安装
    前端开发之jQuery位置属性和筛选方法
  • 原文地址:https://www.cnblogs.com/ruthank/p/11366209.html
Copyright © 2011-2022 走看看