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

 

  

posted @ 2018-09-26 22:54  StarHai  阅读(261)  评论(0编辑  收藏  举报