zoukankan      html  css  js  c++  java
  • 圆和多边形交模板

    牛客网暑期ACM多校训练营(第三场)J

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #define max(x,y) ((x)>(y)?(x):(y))
    #define min(x,y) ((x)<(y)?(x):(y))
    #define PI acos(-1.0)
    #define EPS 1e-7
    using namespace std;
     
    inline int DB(double x) {
        if(x<-EPS) return -1;
        if(x>EPS) return 1;
        return 0;
    }
     
     
    struct point {
        double x,y;
     
        point() {}
        point(double _x,double _y):x(_x),y(_y) {}
     
        point operator-(point a) {
            return point(x-a.x,y-a.y);
        }
        point operator+(point a) {
            return point(x+a.x,y+a.y);
        }
     
        double operator*(point a) {
            return x*a.y-y*a.x;
        }
     
        point oppose() {
            return point(-x,-y);
        }
     
        double length() {
            return sqrt(x*x+y*y);
        }
     
        point adjust(double L) {
            L/=length();
            return point(x*L,y*L);
        }
     
        point vertical() {
            return point(-y,x);
        }
     
        double operator^(point a) {
            return x*a.x+y*a.y;
        }
    };
     
     
    struct segment {
        point a,b;
     
        segment() {}
        segment(point _a,point _b):a(_a),b(_b) {}
     
        point intersect(segment s) {
            double s1=(s.a-a)*(s.b-a);
            double s2=(s.b-b)*(s.a-b);
            double t=s1+s2;
            s1/=t;
            s2/=t;
            return point(a.x*s2+b.x*s1,a.y*s2+b.y*s1);
        }
        point vertical(point p) {
            point t=(b-a).vertical();
            return intersect(segment(p,p+t));
        }
        int isonsegment(point p) {
            return DB(min(a.x,b.x)-p.x)<=0&&
                   DB(max(a.x,b.x)-p.x)>=0&&
                   DB(min(a.y,b.y)-p.y)<=0&&
                   DB(max(a.y,b.y)-p.y)>=0;
        }
    };
     
    struct circle {
        point p;
        double R;
    };
     
    circle C;
    point p[205];
    int n;
     
     
    double cross_area(point a,point b,circle C) {
        point p=C.p;
        double R=C.R;
        int sgn=DB((b-p)*(a-p));
        double La=(a-p).length(),Lb=(b-p).length();
        int ra=DB(La-R),rb=DB(Lb-R);
        double ang=acos(((b-p)^(a-p))/(La*Lb));
        segment t(a,b);
        point s;
        point h,u,temp;
        double ans,L,d,ang1;
     
        if(!DB(La)||!DB(Lb)||!sgn) ans=0;
        else if(ra<=0&&rb<=0) ans=fabs((b-p)*(a-p))/2;
        else if(ra>=0&&rb>=0) {
            h=t.vertical(p);
            L=(h-p).length();
            if(!t.isonsegment(h)||DB(L-R)>=0) ans=R*R*(ang/2);
            else {
                ans=R*R*(ang/2);
                ang1=acos(L/R);
                ans-=R*R*ang1;
                ans+=R*sin(ang1)*L;
            }
        } else {
            h=t.vertical(p);
            L=(h-p).length();
            s=b-a;
            d=sqrt(R*R-L*L);
            s=s.adjust(d);
            if(t.isonsegment(h+s)) u=h+s;
            else u=h+s.oppose();
            if(ra==1) temp=a,a=b,b=temp;
            ans=fabs((a-p)*(u-p))/2;
            ang1=acos(((u-p)^(b-p))/((u-p).length()*(b-p).length()));
            ans+=R*R*(ang1/2);
        }
        return ans*sgn;
    }
     
    double cal_cross(circle C,point p[],int n) {
        double ans=0;
        int i;
        p[n]=p[0];
        for(i=0; i<n; i++) ans+=cross_area(p[i],p[i+1],C);
        return fabs(ans);
    }
     
     
    int main()
    {
        while(scanf("%d", &n)!=EOF){
     
            for(int i=0;i<n;i++) scanf("%lf%lf", &p[i].x, &p[i].y);
            double area1 = 0;
            for(int i = 0; i < n; i++) {
                int nx = (i + 1) % n;
                area1 += p[i] * p[nx];
            }
     
            if(area1 < 0) area1 = -area1;
            area1 /= 2;
     
            int q; scanf("%d", &q);
            while(q--) {
                scanf("%lf%lf", &C.p.x, &C.p.y);
                double a, b, tar;
                scanf("%lf%lf", &a, &b);
                double area2 = area1 * (1 - a / b);
    //            printf("%.3f
    ", area2);
                double l = 0, r = 3e4;
     
    //            printf("%.3f %.3f
    ", o.x, o.y);
                for(int i = 1; i <= 60; i++) {
                    double mid = (l + r) / 2;
                    C.R = mid;
                    double area = cal_cross(C, p, n);
                    if(area >= area2) r = mid;
                    else l = mid;
                }
     
                printf("%.12f
    ", l);
            }
        }
        return 0;
    }
    /********************
    4
    0 0
    1 0
    2 0
    3 0
    1
    1 1 1 2
    ********************/
    
  • 相关阅读:
    UVa 11384 Help is needed for Dexter (递归)
    HDU 4355 Party All the Time (三分求极值)
    UVa 11992 Fast Matrix Operations (线段树,区间修改)
    LA 3708 && POJ 3154 Graveyard (思维)
    LA 3942 && UVa 1401 Remember the Word (Trie + DP)
    LA 4329 Ping pong (树状数组)
    HDU 2058 The sum problem (数学+暴力)
    POJ 1458 Common Subsequence (DP+LCS,最长公共子序列)
    代理服务器
    .net垃圾回收
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/9377393.html
Copyright © 2011-2022 走看看