码迷,mamicode.com
首页 > 其他好文 > 详细

HDU5120 - Intersection

时间:2018-09-27 00:05:09      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:hdu5120   scanf   eps   cti   turn   cal   ase   swap   its   

HDU5120 - Intersection


做法:答案就是\(A1 \cap B1 - A2 \cap B1 - A1 \cap B2 + A2 \cap B2\),圆形面积交码了好久,先把两个圆转到x轴上,大的放到原点,小的放在大圆的左边,计算一下交点坐标,然后讨论即可。

#include <bits/stdc++.h>
#define pb push_back
typedef long long ll;
const double eps = 1e-10;
const double PI = acos(-1.0);
using namespace std;
int sgn(double x) {
    if(fabs(x) < eps) return 0;
    if(x < 0) return -1;
    return 1;
}
int n;
struct cir{
    double x,y,r;
    cir(){}
    cir(double _x,double _y,double _r) {
        x=_x; y=_y; r=_r;
    }
    void output() {
        cout << x <<‘ ‘<< y <<‘ ‘<< r << endl;
    }
}a1, a2, b1, b2;
double dis(double ax,double ay,double bx,double by) {
    return sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by));
}
double area_t(double a,double b,double c) {
    if(a+b <= c) return 0;
    if(a+c <= b) return 0;
    if(c+b <= a) return 0;
    if(abs(a-b) >= c) return 0;
    if(abs(c-b) >= b) return 0;
    if(abs(a-c) >= a) return 0;

    double p = (a+b+c)*0.5;
    return sqrt((p-a)*(p-b)*(p-c)*p);
}
void chg(cir &a, cir &b) {
    if(a.r < b.r) swap(a,b);
    double D = dis(a.x,a.y,b.x,b.y);
    a.x = a.y = 0;
    b.x = D; b.y = 0;
}
double cal(cir a, cir b) {
    chg(a, b);
    double D = dis(a.x,a.y,b.x,b.y), ans = 0;
    if(sgn(D- (a.r+b.r))>= 0) return 0;
    if(sgn(a.r-b.r-D)>=0) return PI*b.r*b.r;
    double cx = (a.r*a.r + D*D - b.r*b.r)*0.5/D;
    double cy = sqrt(a.r*a.r - cx*cx);
    if(sgn(cx - b.x) <= 0) {
        double S1 = D*cy;
        double tha = asin(cy/a.r)*2;
        double thb = asin(cy/b.r)*2;
        double Sa = a.r*a.r*tha*0.5;
        double Sb = b.r*b.r*thb*0.5;
        ans = Sa + Sb - S1;
    }
    else {
        double tha = asin(cy/a.r)*2;
        double thb = 2*PI-asin(cy/b.r)*2;
        double Sa = a.r*a.r*tha*0.5 - area_t(a.r,a.r,cy*2);
        double Sb = b.r*b.r*thb*0.5 + area_t(b.r,b.r,cy*2);
        ans = Sa + Sb;
    }
    return ans;
}
int T, CC = 0;
int main() {
    scanf("%d",&T);
    while(T--) {double r,R,tx1,tx2,ty1,ty2;
        scanf("%lf%lf",&r,&R);
        scanf("%lf%lf",&tx1,&ty1);
        scanf("%lf%lf",&tx2,&ty2);
        a1 = cir(tx1,ty1,R);
        a2 = cir(tx1,ty1,r);
        b1 = cir(tx2,ty2,R);
        b2 = cir(tx2,ty2,r);
        double ans = cal(a1,b1) - cal(a2,b1) - cal(a1,b2) + cal(a2,b2);
        printf("Case #%d: %.6f\n",++CC,ans);
    }
}

HDU5120 - Intersection

标签:hdu5120   scanf   eps   cti   turn   cal   ase   swap   its   

原文地址:https://www.cnblogs.com/RRRR-wys/p/9710574.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!