HDU 5120 Intersection(几何模板题)

题意:给定两个圆环,求两个圆环相交的面积。

思路:由于圆心和半径不一样,分了好多种情况,后来发现只要把两个圆相交的函数写好之后就不需要那么复杂了。两个圆相交的面积的模板如下:

double area_of_overlap(point c1, double r1, point c2, double r2)
{
    double d = dist(c1, c2);
    if (sgn(d - r1 - r2) >= 0) return 0;
    if (sgn(fabs(r1 - r2) - d) >= 0)
    {
        double r = min(r1, r2);
        return PI * r * r;
    }
    double x = (d * d + r1 * r1 - r2 * r2) / (2.0 * d);
    double t1 = acos(x / r1);
    double t2 = acos((d - x) / r2);
    return r1 * r1 * t1 + r2 * r2 * t2 - d * r1 * sin(t1);
}

其实是求的这个面积:

完整代码如下:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>

using namespace std;
typedef long long ll;
const double eps = 1e-8;
const double PI = acos(0) * 2;
int sgn(double x)//精度控制函数
{
    if (fabs(x) < eps) return 0;
    return x > 0 ? 1 : -1;
}
//点的定义
struct point {
    double x, y;
    point (double x = 0, double y = 0):x(x), y(y) {}
};
//获得两点的距离
double dist(const point &a, const point &b)
{
    double x = (a.x - b.x) * (a.x - b.x);
    double y = (a.y - b.y) * (a.y - b.y);
    return sqrt(x + y);
}
//求两个圆相交的面积,如果不相交返回0,c1为第一个圆心坐标,r1为第一个圆的半径,c2为第二个圆心坐标, r2为第二个圆的半径
double area_of_overlap(point c1, double r1, point c2, double r2)
{
    double d = dist(c1, c2);
    if (sgn(d - r1 - r2) >= 0) return 0;
    if (sgn(fabs(r1 - r2) - d) >= 0)
    {
        double r = min(r1, r2);
        return PI * r * r;
    }
    double x = (d * d + r1 * r1 - r2 * r2) / (2.0 * d);
    double t1 = acos(x / r1);
    double t2 = acos((d - x) / r2);
    return r1 * r1 * t1 + r2 * r2 * t2 - d * r1 * sin(t1);
}//下面此题求两个圆环相交的面积
int main()
{
    int T, kase = 0;
    point a, b;
    double r, R;
    scanf("%d", &T);
    while (T--)
    {
        scanf("%lf %lf", &r, &R);
        scanf("%lf %lf %lf %lf", &a.x, &a.y, &b.x, &b.y);
        double tot = area_of_overlap(a, R, b, R);
        double s1 = area_of_overlap(a, R, b, r);
        double s2 = area_of_overlap(a, r, b, r);
        printf("Case #%d: %.6f\n", ++kase, tot - 2.0 * s1 + s2);
    }
    return 0;
}
时间: 2024-12-24 19:37:52

HDU 5120 Intersection(几何模板题)的相关文章

POJ 3528 hdu 3662 三维凸包模板题

POJ 3528题:http://poj.org/problem?id=3528 HDU 3662:http://acm.hdu.edu.cn/showproblem.php?pid=3662 一个是求三维凸包面数,一个是求三维凸包表面积,都是很裸的. 贴代码: #include<stdio.h> #include<algorithm> #include<string.h> #include<math.h> #include<stdlib.h>

HDU 1251 Trie树模板题

1.HDU 1251 统计难题  Trie树模板题,或者map 2.总结:用C++过了,G++就爆内存.. 题意:查找给定前缀的单词数量. #include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<cstdio> #define max(a,b) a>b?a:b #define F(i,a,b

hdu 1711 KMP算法模板题

题意:给你两个串,问你第二个串是从第一个串的什么位置開始全然匹配的? kmp裸题,复杂度O(n+m). 当一个字符串以0为起始下标时.next[i]能够描写叙述为"不为自身的最大首尾反复子串长度". 当发生失配的情况下,j的新值next[j]取决于模式串中T[0 ~ j-1]中前缀和后缀相等部分的长度, 而且next[j]恰好等于这个最大长度. 防止超时.注意一些细节.. 另外:尽量少用strlen.变量记录下来使用比較好,用字符数组而不用string //KMP算法模板题 //hdu

HDU 2222 AC自动机模板题

题目: http://acm.hdu.edu.cn/showproblem.php?pid=2222 AC自动机模板题 1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 using namespace std; 5 char key[55]; 6 char des[1111111]; 7 struct node{ 8 node *fail; 9 node *next[26]; 10 int cnt;

HDU 3065 (AC自动机模板题)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 题目大意:多个模式串,范围是大写字母.匹配串的字符范围是(0~127).问匹配串中含有哪几种模式串,且每种模式串出现了多少次. 解题思路: AC自动机模板题.模式串的范围是大写字母,但是匹配串的范围却是(0~127). 如果Trie 开到 128 加上不回收内存,就会MLE. 实际上开到26就行了,find的时候对于c<0||c>26,强制令pos=root出现失配,并开始下一个字符就行了

HDU 2896 (AC自动机模板题)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2896 题目大意:多个模式串.多个匹配串.其中串的字符范围是(0~127).问匹配串中含有哪几个模式串. 解题思路: AC自动机模板题.注意一下字符范围. cnt记录这个模式串的个数改为这个模式串的index. find的时候,把找到的index压入vector里面即可. 注意有多个匹配串,每次find之后会把last->cnt修改,原因是防止一个模式串出现了多次被压入vector,所以先备份一下,

HDU 5901 Count primes (模板题)

题意:给求 1 - n 区间内的素数个数,n <= 1e11. 析:模板题. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream> #include <cstrin

HDU 1166 线段树模板题

坐了3天的火车,终于到外婆家了(┬_┬).这次北京之旅颇有感触,虽然学到的东西不是很多(主要是自己的原因,没有认真学,并不是老师讲的不好),不过出去见见世面也是好的.最后一场比赛印象颇深,被虐的有点惨....记得当时有道题感觉自己能过,想用数组模拟链表水过,可是无论怎么优化一直超时@[email protected]后面比完后听朋友说那题应该用线段树做,顿时恍然大悟,然并卵,线段树的模板早忘了.....今天做道线段树的模板题先复习一下,过会再想想那道题. 敌兵布阵 Time Limit: 200

Number Sequence - HDU 1711(KMP模板题)

题意:给你一个a串和一个b串,问b串是否是a串的子串,如果是返回b在a中最早出现的位置,否则输出-1 分析:应该是最简单的模板题了吧..... 代码如下: ============================================================================================== #include<stdio.h> #include<string.h> const int MAXM = 1e4+7; const int