NYOJ 1186 心理阴影(两个圆环的相交面积)

心理阴影

时间限制:1000 ms  |  内存限制:65535 KB

难度:2

描述
      自从shanghai reginal后,zkc学长的心理就有了阴影。什么不敢水题,不敢gj,不敢放松...(各种不敢)。同样的你们的zsj学长也是这样的。并且他们的心理阴影是一样一样的。

已知一个人的心理阴影为一个环形,那么求你们的zkc学长和zjs学长站在一起的时候的心理阴影的重叠面积。

输入
T组数据

r,R表示是内圆半径和外圆半径。

x1,y1 zkc学长站的位置(抽象为一个点)

x2,y2 zjs学长站的位置(也抽象为一个点)

输出
Case #k: y

ps:k,第k组数据。y,你们的zkc学长和zjs学长站在一起的时候的心理阴影的重叠面积。

样例输入
2
2 3
0 0
0 0
2 3
0 0
5 0
样例输出
Case #1: 15.70796
Case #2: 2.25078

经分析可得:

两个圆环的相交面积 = 圆环1外圆和圆环2外圆的相交面积 - 圆环1外圆和圆环2内圆的相交面积 - 圆环1内圆和圆环2外圆的相交面积 + 圆环1内圆和圆环2内圆的相交面积。

#include <cstdio>
#include <cmath>
using namespace std;

#define PI acos(-1.0) //定义PI

struct Circle { // 定义圆
    double x, y;
    double r;
};

struct Ring { // 定义圆环
    double x, y;
    double R, r;
};

struct Get_Intersection_RingAndRing {

    //求圆心距,即两个圆心之间的距离
    double get_dis(double x1, double y1, double x2, double y2) {
        return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    }

    // 求两圆的相交面积
    double get_CircleIntersectionArea(Circle c1, Circle c2) {
        double dis = get_dis(c1.x, c1.y, c2.x, c2.y);

        // 圆心距大于半径和,两圆相交面积为0
        if(dis >= c1.r + c2.r) return 0;

        double min_r = c1.r < c2.r ? c1.r : c2.r;
        double max_r = c1.r > c2.r ? c1.r : c2.r;
        if(min_r + dis <= max_r)  //圆心距小于半径之差,两圆包含关系
            return PI * min_r * min_r;

        double a = acos((c1.r * c1.r + dis * dis - c2.r * c2.r) / 2 / c1.r / dis);
        double b = acos((c2.r * c2.r + dis * dis - c1.r * c1.r) / 2 / c2.r / dis);
        double area1 = a * c1.r * c1.r; //第一个圆中扇形的面积, 弧长L=a*c1.r,面积等于0.5*L*c1.r
        double area2 = b * c2.r * c2.r; //第二个圆中扇形的面积
        double ans = area1 + area2; //两个扇形的面积和等于四边形的面积加上两圆相交的面积
        double area_qua = sin(a) * c1.r * dis; //四边形的面积
        ans -= area_qua;
        return ans;
    }

    //求圆环和圆环的相交面积
    double Get_IntersectionArea(Ring r1, Ring r2) {
        Circle a1, a2, b1, b2;
        a1.x = r1.x, a1.y = r1.y, a1.r = r1.r;
        a2.x = r1.x, a2.y = r1.y, a2.r = r1.R;
        b1.x = r2.x, b1.y = r2.y, b1.r = r2.r;
        b2.x = r2.x, b2.y = r2.y, b2.r = r2.R;
        return get_CircleIntersectionArea(a2, b2) - get_CircleIntersectionArea(a1, b2) - get_CircleIntersectionArea(a2, b1) + get_CircleIntersectionArea(a1, b1);
    }
};

int main()
{
    int T;
    Ring r1, r2;
    Get_Intersection_RingAndRing x;
    scanf("%d", &T);
    for(int cas = 1; cas <= T; cas++) {
        scanf("%lf%lf", &r1.r, &r1.R);
        r2.r = r1.r, r2.R = r1.R;
        scanf("%lf%lf%lf%lf", &r1.x, &r1.y, &r2.x, &r2.y);
        printf("Case #%d: %.5lf\n", cas, x.Get_IntersectionArea(r1, r2));
    }
    return 0;
}
时间: 2024-11-05 16:38:41

NYOJ 1186 心理阴影(两个圆环的相交面积)的相关文章

HDU 5120 Intersection (求圆环相交面积)

题意:给定圆环的内径r和外径R,以及2个相同圆环的圆心,求两个圆环的相交面积. 思路: S = A大B大 - A大B小 - A小B大 + A小B小.(A表示A环,大表示大圆,B同) 1 #include <iostream> 2 #include <queue> 3 #include <stack> 4 #include <cstdio> 5 #include <vector> 6 #include <map> 7 #include

poj 2546 Circular Area (两圆相交面积)

链接:poj 2546 题意:已知两圆的圆心和半径,求两圆相交部分的面积 分析:两圆的位置关系有三种:相离,相交,内含 相离时:相交面积为0 相交时,大扇形面积+小扇形面积-四边形面积 内含时,相交面积为小圆面积 #include<stdio.h> #include<math.h> #define PI acos(-1.0) typedef struct stu { double x,y; }point; double Distance(point a,point b) { ret

hdu5012 圆环相交面积

题中给了 两个同心圆, 一个大圆一个小圆,然后再给了一个大圆一个小圆也是同心圆,求这两个圆环相交的面积,用两个大圆面积减去两倍大小圆面积交加上两个小圆面积交,就ok了 这里算是坑明白了 使用acos的时候要保证不能让大于1或者小于-1的数进来,因此加一个判断,在现场的时候就是这里被坑死了 #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include &

Torch 两个矩形框重叠面积的计算 (IoU between tow bounding box)

Torch 两个矩形框重叠面积的计算 (IoU between tow bounding box) 1 function DecideOberlap(BBox_x1, BBox_y1, BBox_x2, BBox_y2, BBox_gt_x1, BBox_gt_y1, BBox_gt_x2, BBox_gt_y2) 2 3 x1 = BBox_x1; 4 y1 = BBox_y1; 5 width1 = BBox_x2 - BBox_x1; 6 height1 = BBox_y2 - BBox_

判断两个链表是否相交(带环)

解决方案: 1.找出链表1的环入口节点a1,链表2的环入口节点a2; 2.如果a1=a2; 说明两个链表可能在入环之前或者入环第一个节点相交:将a1,a2作为两个链表的最后一个节点,转化为不带环的链表相交:其实在这种情况下已经说明两个链表已经相交了. 3.如果a1!=a2;以a1为基准节点进行while循环,如果在循环中找到跟a2相同的节点,说明两个链表相交:如果没找到,说明不相交. #如果1个链表不带环,1个链表带环:则两个链表必不相交:

判断两个线段是否相交

我们的问题是这样的:给定一条线段的起点为$A_1$.终点为$A_2$,另一条线段的起点为$B_1$.终点为$B_2$,问线段$A_1A_2$和线段$B_1B_2$是否相交? 我们首先解释一下,两条线段相交的概念是指,存在一个点,这个点同时在两条线段上. 方法一(解方程法): 容易知道,线段$A_1A_2$上的点的集合为$A = A_1 * (1 - r_1) + A_2 * r_1$,其中$r_1 \in [0, 1]$:同理,线段$B_1B_2$上的点的集合为$B = B_1 * (1 - r

链表相交问题:判断两个链表是否相交,若相交求交点

默认为不带环链表,若带环则延伸为判断链表是否带环,若带环,求入口点 看看两个链表相交到底是怎么回事吧,有这样的的几个事实:(假设链表中不存在环) (1)一旦两个链表相交,那么两个链表中的节点一定有相同地址. (2)一旦两个链表相交,那么两个链表从相交节点开始到尾节点一定都是相同的节点. #include<iostream> #include<assert.h> using namespace std; template<class T> struct LinkNode

poj1039——计算几何 求直线与线段交点,判断两条直线是否相交

poj1039——计算几何  求直线与线段交点,判断两条直线是否相交 Pipe Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9439   Accepted: 2854 Description The GX Light Pipeline Company started to prepare bent pipes for the new transgalactic light pipeline. During the de

10.两个单链表相交,计算相交点

10.两个单链表相交,计算相交点 思路1: 分别遍历两个单链表,计算出它们的长度M和N,假设M比N大,则长度M的链表先前进M-N,然后两个链表同时以步长1前进,前进的同时比较当前的元素,如果相同,则必是交点.Node* getIntersectPoint(Node* Head1,Node* Head2) //两链表相交,计算相交点 Node* getIntersectPoint(Node* Head1,Node* Head2) {   int len1=numOfNodes(Head1);