zoukankan      html  css  js  c++  java
  • HDU 5120 Intersection

    Intersection

    Time Limit: 4000/4000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)
    Total Submission(s): 4238    Accepted Submission(s): 1623


    Problem Description
    Matt is a big fan of logo design. Recently he falls in love with logo made up by rings. The following figures are some famous examples you may know.


    A ring is a 2-D figure bounded by two circles sharing the common center. The radius for these circles are denoted by r and R (r < R). For more details, refer to the gray part in the illustration below.


    Matt just designed a new logo consisting of two rings with the same size in the 2-D plane. For his interests, Matt would like to know the area of the intersection of these two rings.
     
    Input
    The first line contains only one integer T (T ≤ 105), which indicates the number of test cases. For each test case, the first line contains two integers r, R (0 ≤ r < R ≤ 10).

    Each of the following two lines contains two integers xi, yi (0 ≤ xi, yi ≤ 20) indicating the coordinates of the center of each ring.
     
    Output
    For each test case, output a single line “Case #x: y”, where x is the case number (starting from 1) and y is the area of intersection rounded to 6 decimal places.
     
    Sample Input
    2 2 3 0 0 0 0 2 3 0 0 5 0
     
    Sample Output
    Case #1: 15.707963 Case #2: 2.250778
     
    Source
     
    Recommend
    liuyiding
    参考代码:
      1 #include <bits/stdc++.h>
      2 #define INF 0x3f3f3f3f
      3 #define rep(i,a,n) for(int i=a;i<n;++i)
      4 #define per(i,a,n) for(int i=n-1;i>=a;--i)
      5 using namespace std;
      6 typedef long long ll;
      7 const double eps = 1e-10;
      8 const double PI = acos(-1.0);
      9 const int maxn = 2500; //注意修改
     10 int n;
     11 //有的命名为sgn函数,高精度符号判断
     12 int dcmp(double x)
     13 {
     14     //相等函数判断,减少精度问题
     15     if(fabs(x) < eps) return 0;
     16     else return x < 0 ? -1 : 1;
     17 }
     18 //点的定义
     19 class Point
     20 {
     21 public:
     22     double x, y;
     23     Point(double x = 0, double y = 0): x(x), y(y) {} //构造函数,方便代码的编写
     24 } point[maxn], pafter[maxn];
     25 
     26 typedef Point Vector;// 从程序实现上,Vector只是Point的别名
     27 
     28 //运算符重载
     29 Vector operator + (const Vector &A, const Vector &B)
     30 {
     31     return Vector(A.x + B.x, A.y + B.y);    //向量+向量=向量,点+向量=点
     32 }
     33 Vector operator - (const Vector &A, const Vector &B)
     34 {
     35     return Vector(A.x - B.x, A.y - B.y);    //向量-向量=向量,点-向量-点
     36 }
     37 Vector operator * (const Vector &A, double p)
     38 {
     39     return Vector(A.x * p, A.y * p);    //向量*数=向量 (数乘)
     40 }
     41 Vector operator / (const Vector &A, double p)
     42 {
     43     return Vector(A.x / p, A.y / p);    //向量/数=向量 (数除)
     44 }
     45 double operator * (const Vector &A, const Vector &B)
     46 {
     47     return A.x * B.x + A.y * B.y;    //向量(点乘)向量=数  (点乘)
     48 }
     49 bool operator < (const Point &A, const Point &B)
     50 {
     51     return A.x == B.x ? A.y < B.y : A.x < B.x;    //按x值递增排序
     52 }
     53 bool operator == (const Point &A, const Point &B)
     54 {
     55     return dcmp(A.x - B.x) == 0 && dcmp(A.y - B.y) == 0;    //判定两个点是否相同,用到dcmp精度判定
     56 }
     57 
     58 //点乘叉乘
     59 double dot(const Vector &A, const Vector &B)
     60 {
     61     return A.x * B.x + A.y * B.y;    //向量(叉乘)向量=向量 (叉乘)
     62 }
     63 double operator ^ (const Vector &A, const Vector &B)
     64 {
     65     return A.x * B.y - A.y * B.x;
     66 }
     67 double cross(const Vector &A, const Vector &B)
     68 {
     69     return A.x * B.y - A.y * B.x;
     70 }
     71 
     72 //模长面积
     73 double abs(const Vector &A)
     74 {
     75     return sqrt(dot(A, A));   //计算向量模长
     76 }
     77 double area2(const Point &A, const Point &B, const Point &C)
     78 {
     79     return cross(B - A, C - A) ;   //计算平行四边形方向面积
     80 }
     81 double PolygonArea(Point *p, int n)
     82 {
     83     double area = 0;    //计算多边形的有向面积
     84     rep(i, 1, n - 1)
     85     {
     86         area += cross(p[i] - p[0], p[i + 1] - p[0]);
     87     }
     88     return area / 2.0;
     89 }
     90 
     91 //旋转
     92 Vector rotate(Vector A, double rad)
     93 {
     94     return Vector(A.x * cos(rad) - A.y * sin(rad), A.x * sin(rad) + A.y * cos(rad));   //旋转rad弧度
     95 }
     96 Vector normal(Vector A)
     97 {
     98     double l = abs(A);    //计算单位法线,左转90
     99     return Vector(-A.y / l, A.x / l);
    100 }
    101 double torad(double deg)
    102 {
    103     return deg / 180 * acos(-1);    //角度转弧度
    104 }
    105 
    106 //线段定义
    107 class Line
    108 {
    109 public:
    110     Point s, e;
    111     Line() {}
    112     Line(Point _s, Point _e)
    113     {
    114         s = _s;
    115         e = _e;
    116     }
    117 
    118 } line[maxn];
    119 bool inter(Line l1, Line l2)
    120 {
    121     return (
    122                max(l1.s.x, l1.e.x) >= min(l2.s.x, l2.e.x) &&
    123                max(l2.s.x, l2.e.x) >= min(l1.s.x, l1.e.x) &&
    124                max(l1.s.y, l1.e.y) >= min(l2.s.y, l2.e.y) &&
    125                max(l2.s.y, l2.e.y) >= min(l1.s.y, l1.e.y) &&
    126                dcmp((l2.s - l1.s) ^ (l1.s - l1.e)) * dcmp((l2.e-l1.s) ^ (l1.s - l1.e)) < 0 &&
    127                dcmp((l1.s - l2.s) ^ (l2.s - l2.e)) * dcmp((l1.e-l2.s) ^ (l2.s - l2.e)) < 0
    128            ) ;
    129 }
    130 
    131 bool inter(Point a1, Point a2, Point b1, Point b2)
    132 {
    133     Line l1(a1, a2), l2(b1, b2);
    134     return inter(l1, l2);
    135 }
    136 
    137 bool cmp(Point a, Point b)
    138 {
    139     if(a.x == b.x) return a.y < b.y;
    140     else return a.x < b.x;
    141 }
    142 
    143 double dist(Point a, Point b)
    144 {
    145     return sqrt((a - b) * (a - b));
    146 }
    147 
    148 //求两直线交点
    149 Point getinter(Line l1, Line l2)
    150 {
    151     Vector v = l1.s - l1.e;
    152     Vector w = l2.s - l2.e;
    153     Vector u = l1.e-l2.e;
    154     double t = cross(w, u) / cross(v, w);
    155     return l1.e+v * t;
    156 }
    157 Point getinter(Point a1, Point a2, Point b1, Point b2)
    158 {
    159     Line l1(a1, a2);
    160     Line l2(b1, b2);
    161     return getinter(l1, l2);
    162 }
    163 //判定点和线段的关系,
    164 //0:不在线段所在直线上
    165 //1:在线段内(不含端点)
    166 //2:在线段端点
    167 //3:在线段两侧的射线上
    168 int  online(Point a, Line l)
    169 {
    170     if(dcmp(cross(l.s - a, l.e-a)) != 0) return 0;
    171     double pans = dcmp(dot(l.s - a, l.e-a));
    172     if(pans < 0) return 1;
    173     else if(pans == 0) return 2;
    174     else if(pans > 0) return 3;
    175 }
    176 
    177 int online(Point a, Point b1, Point b2)
    178 {
    179     Line l(b1, b2);
    180     return online(a, l);
    181 }
    182 
    183 int sgn(double x)
    184 {
    185     if(fabs(x) < eps) return 0;
    186     if(x < 0) return -1;
    187     else return 1;
    188 }
    189 
    190 double Area_of_overlap(Point c1, double r1, Point c2, double r2)
    191 {
    192     double d = dist(c1, c2);
    193     if(r1 + r2 < d + eps) return 0;
    194     if(d < fabs(r1 - r2) + eps)
    195     {
    196         double r = min(r1, r2);
    197         return PI * r * r;
    198     }
    199     double x = (d * d + r1 * r1 - r2 * r2) / (2 * d);
    200     double t1 = acos(x / r1);
    201     double t2 = acos((d - x) / r2);
    202     return r1 * r1 * t1 + r2 * r2 * t2 - d * r1 * sin(t1);
    203 }
    204 
    205 int t;
    206 double RR, rr;
    207 double xx1, yy1, xx2, yy2;
    208 int main()
    209 {
    210     ios::sync_with_stdio(false);
    211     cin >> t;
    212     rep(tt, 1, t + 1)
    213     {
    214         cin >> rr >> RR >> xx1 >> yy1 >> xx2 >> yy2;
    215         double ans1, ans2, ans3, ans4;
    216         ans1 = Area_of_overlap(Point(xx1, yy1), RR, Point(xx2, yy2), RR);
    217         ans2 = Area_of_overlap(Point(xx1, yy1), RR, Point(xx2, yy2), rr);
    218         ans3 = Area_of_overlap(Point(xx1, yy1), rr, Point(xx2, yy2), RR);
    219         ans4 = Area_of_overlap(Point(xx1, yy1), rr, Point(xx2, yy2), rr);
    220         cout << "Case #" << tt << ": ";
    221         cout << fixed << setprecision(6) << ans1 - ans2 - ans3 + ans4 << endl;
    222     }
    223     return 0;
    224 }
    View Code

      

  • 相关阅读:
    IFRAME自适应高度
    项目支出数据产生过程
    hbase体系结构以及说明
    PLSQL 设置
    hadoop编程模型
    捕捉桌面上的窗口信息
    在不修改代码的情况下无限扩展应用项目
    跟我一起玩Win32开发(25):监视剪贴板
    跟我一起玩Win32开发(24):计时器
    跟我一起玩Win32开发(23):渐变颜色填充
  • 原文地址:https://www.cnblogs.com/csushl/p/9710620.html
Copyright © 2011-2022 走看看