zoukankan      html  css  js  c++  java
  • HDU 5120 Intersection(2014北京赛区现场赛I题 计算几何)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5120

    解题报告:给你两个完全相同的圆环,要你求这两个圆环相交的部分面积是多少?

    题意看了好久没懂。圆环由一个大圆里面套一个小圆,中间部分就是圆环,两圆环相交面积 = 大圆相交的面积 - 2*大圆与小圆相交的面积 + 小圆与小圆相交的面积。

    也就是说,这题就可以化为求两个圆的相交的面积了。可以利用两个圆的方程,求出圆的交点所在的直线,然后求出圆心到这条直线的距离,就可以求出两个圆对应的扇形的圆心角是多少了。要注意的地方就是,注意两个圆的位置关系,可能是相交,包含,或者相离,其中相交的情况下,还要注意较小的那个圆的扇形的圆心角是不是钝角,可以通过判断两个圆心的位置是 不是在圆的交点所在直线的同一侧,判断这个可以将两个圆心代入直线方程,乘积小于0,说明这两个点在这条直线的两侧。然后,如果是圆心在交点所在直线的同一侧,那么,求这部分相交的面积的时候,应该用小圆扇形的面积加上那个三角形的面积,否则就是扇形面积减去那个三角形的面积。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 const double PI = acos(-1.0),eps = 1e-9;
     8 struct point
     9 {
    10     double x,y;
    11 };
    12 struct circle
    13 {
    14     point c;
    15     double r;
    16 };
    17 
    18 circle  A,a,B,b;
    19 double dis(point a,point b)
    20 {
    21     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    22 }
    23 double dis_line(point p,double a,double b,double c)
    24 {
    25     return(fabs(a*p.x+b*p.y+c)/sqrt(a*a+b*b));
    26 }
    27 double get_in(circle x,circle y)     //求两 园交集的面积
    28 {
    29     if(dis(x.c,y.c) < (x.r-y.r) || fabs(dis(x.c,y.c) - (x.r-y.r)) < eps) return PI * y.r*y.r;
    30     if(dis(x.c,y.c) > x.r+y.r || fabs(dis(x.c,y.c)-(x.r+y.r)) < eps) return 0;
    31     double a = 2.0 * (x.c.x - y.c.x),b = 2.0 * (x.c.y-y.c.y),c = y.c.x*y.c.x-x.c.x*x.c.x + y.c.y*y.c.y-x.c.y*x.c.y+x.r*x.r-y.r*y.r;
    32     double l1 = dis_line(x.c,a,b,c);
    33     double co1 = acos(l1 / x.r) * 2.0;
    34     double s1 = PI * x.r*x.r*(co1/PI/2.0) - (0.5*x.r*x.r*sin(co1));
    35     double l2 = dis_line(y.c,a,b,c);
    36     double co2 = acos(l2 / y.r) * 2.0,s2;
    37     if((a*x.c.x+b*x.c.y+c) * (a*y.c.x+b*y.c.y+c) <= 0)     //两圆心在园交点的两侧
    38     s2 = PI * y.r*y.r*(co2 / PI/2.0) - (0.5*y.r*y.r*sin(co2));
    39     else s2 = PI * y.r*y.r*((2.0*PI-co2)/(2.0*PI)) + (0.5*y.r*y.r*sin(co2));
    40     return s1+s2;
    41 }
    42 
    43 
    44 int main()
    45 {
    46  //   freopen("in","r",stdin);
    47     int T,kase = 1;
    48     scanf("%d",&T);
    49     while(T--)
    50     {
    51         double r1,r2;
    52         scanf("%lf%lf",&r1,&r2);
    53         scanf("%lf%lf",&A.c.x,&A.c.y);
    54         a = A;
    55         scanf("%lf%lf",&B.c.x,&B.c.y);
    56         b = B;
    57         A.r = B.r = r2;
    58         a.r = b.r = r1;
    59         double ans = get_in(A,B);
    60   //      printf("%lf
    ",get_in(A,B));
    61         ans -= (2.0 * get_in(A,b));
    62     //    printf("%lf
    ",get_in(A,b));
    63         ans += get_in(a,b);
    64    //     printf("%lf
    ",get_in(a,b));
    65         printf("Case #%d: %lf
    ",kase++,ans+eps);
    66     }
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    visual C sharp express from 360 free download
    Druid 在小米公司部分技术实践-博客-云栖社区-阿里云
    公司业务-猫眼知健康
    Sculptor
    可译网 —— 翻译可以更简单
    牛客网-专业IT笔试面试备考平台,最全C++JAVA前端求职题库,全面提升IT编程能力
    设置Redis的LRU策略
    springboot中使用aop技术
    elasticSearch的部署和使用
    jvm原理和代码运行的过程
  • 原文地址:https://www.cnblogs.com/xiaxiaosheng/p/4132386.html
Copyright © 2011-2022 走看看