Everything Has Changed(HDU6354+圆交+求周长)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6354

题目:

题意:用一堆圆来切割一个圆心为原点,半径为R的圆A,问切割完毕后圆A外围剩余部分的周长(图中的红线部分)。

思路:首先判定圆与圆A的关系,这题我们只需要与A内切、相交的圆。然后就是求每个圆把圆A切割掉多少周长,增加了多少周长(因为圆A被切割的部分在切割后绝对是内凹的,此时周长是增加的),内切的时候直接加上切割圆的周长(如最上面的那个小圆),相交的圆部分我采用的方法是用余弦定理(A的半径记为R,切割圆半径为r,二者的圆心距离为d,圆心的连线与 圆A和一个交点的夹角为a,则2*d*R*cosa=R*R+d*d-r*r)求出夹角a,再用弧长公式l=a*r求出弧长最后进行加减即可。

代码实现如下:

 1 #include <set>
 2 #include <map>
 3 #include <queue>
 4 #include <stack>
 5 #include <cmath>
 6 #include <bitset>
 7 #include <cstdio>
 8 #include <string>
 9 #include <vector>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15
16 typedef long long ll;
17 typedef pair<ll, ll> pll;
18 typedef pair<ll, int> pli;
19 typedef pair<int, ll> pil;;
20 typedef pair<int, int> pii;
21 typedef unsigned long long ull;
22
23 #define lson i<<1
24 #define rson i<<1|1
25 #define bug printf("*********\n");
26 #define FIN freopen("D://code//in.txt", "r", stdin);
27 #define debug(x) cout<<"["<<x<<"]" <<endl;
28 #define IO ios::sync_with_stdio(false),cin.tie(0);
29
30 const double eps = 1e-8;
31 const int mod = 10007;
32 const int maxn = 1e6 + 7;
33 const double pi = acos(-1);
34 const int inf = 0x3f3f3f3f;
35 const ll INF = 0x3f3f3f3f3f3f3f;
36
37 typedef struct stu {
38     double x,y;
39 } point;
40
41 double Distance(point a,point b) {
42     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
43 }
44
45 double Inter(point a,double R,point b,double r) { //变化的周长
46     double dis=Distance(a,b);
47     double angle1=acos((R*R+dis*dis-r*r)/(2.0*R*dis));
48     double angle2=acos((r*r+dis*dis-R*R)/(2.0*r*dis));
49     double s=r*angle2*2-R*angle1*2;
50     return s;
51 }
52
53 int t, m, R;
54 double x, y, r, ans;
55 stu o, p;
56
57 int main() {
58     //FIN;
59     scanf("%d", &t);
60     while(t--) {
61         scanf("%d%d", &m, &R);
62         ans = 2 * pi * R;
63         o.x = 0, o.y = 0;
64         for(int i = 1; i <= m; i++) {
65             scanf("%lf%lf%lf", &x, &y, &r);
66             p.x = x, p.y = y;
67             double d = Distance(o, p);
68             if(d - R - r >= eps) continue; //外离
69             if(fabs(R - r) - d > eps) continue; //内离
70             if(R == r + d) { //内切
71                 ans += 2 * pi * r;
72             } else { //相交
73                 ans += Inter(o, R, p, r);
74             }
75         }
76         printf("%.12f\n", ans);
77     }
78     return 0;
79 }

原文地址:https://www.cnblogs.com/Dillonh/p/9433714.html

时间: 2024-10-26 23:30:28

Everything Has Changed(HDU6354+圆交+求周长)的相关文章

CF 337D 求圆交

题目链接:http://codeforces.com/problemset/problem/337/D 题意:就是一棵树上,有一些点被来自东方的神秘力量影响的,力量影响范围是d,为可能的力量源有几个. 思路:相当于是找到距离这m的点的距离都不小于d的点的个数. 先从任意一个点一次dfs,找到m个点中距离最远的点,标记为max1,在以max1开始,dfs一遍,从数组d1记录各个点的距离,找到距离最远的点max2,再从max2开始跑一遍dfs,用d2记录距离.遍历所有点,到max1和max2的距离都

hdu6354 Everything Has Changed (圆的相交弧长)

题目传送门 题意: 用一堆圆来切割一个圆心为原点,半径为R的圆A,问切割完毕后圆A外围剩余部分的周长(图中的红线部分). 思路: 首先判定圆与圆A的关系,这题我们只需要与A内切.相交的圆. 然后就是求每个圆把圆A切割掉多少周长,增加了多少周长(因为圆A被切割的部分在切割后绝对是内凹的,此时周长是增加的), 内切的时候直接加上切割圆的周长(如最上面的那个小圆), 相交的圆部分我采用的方法是用余弦定理 (A的半径记为R,切割圆半径为r,二者的圆心距离为d,圆心的连线与 圆A和一个交点的夹角为a,则2

hdu 1348 (凸包求周长)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 Wall Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3229    Accepted Submission(s): 919 Problem Description Once upon a time there was a greedy

HDU3264 Open-air shopping malls (圆交+二分)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3264 题意: 给定n个圆的圆心和半径,求一个圆心为这些圆中任意一个,与所有圆相交的面积超过其面积一半的圆的最小半径. 分析: 枚举圆心,然后二分得到最小的半径,直接套求圆交的模板. 代码如下: #include <iostream> #include <cstring> #include <cstdio> #include <cmath> using name

Intersection(HDU5120 + 圆交面积)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5120 题目: 题意: 求两个圆环相交的面积. 思路: 两个大圆面积交-2×大圆与小圆面积交+两小圆面积交. 代码实现如下: 1 #include <set> 2 #include <map> 3 #include <deque> 4 #include <ctime> 5 #include <stack> 6 #include <cmath&g

hdu6354 /// 圆的相交

题目大意: 给定m r 初始圆盘以原点为圆心半径为r 给定m个圆的圆心(x,y) 半径r 保证m个圆互不相交且不会覆盖圆盘 用这m个圆来切割初始的圆盘求最后圆盘外围的长度 求圆与圆盘的交点 减去圆盘上两点间的周长 加上圆上两点间的周长 判断一下方向 #include <bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f #define LL long long #define PI acos(-1) #define pb(a)

c++-面向对象类的示例-求周长面积,判断体积相等-文件操作和一般操作

面向对象编程示例:求周长和面积 #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; //圆的周长 double getCircleGirth(double r) { return 2 * 3.14*r; } //源的面积 double getCircleArea(double r) { return 3.14*r*r; } //用面向对象实现 //圆类 class Circle { public: v

POJ 2540 半平面交求可行区域面积

Hotter Colder Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2343   Accepted: 981 Description The children's game Hotter Colder is played as follows. Player A leaves the room while player B hides an object somewhere in the room. Player

POJ 1177 Picture(扫描线求周长)

与求面积并的差不多,但是这个与扫描的方向相同的情况不太好处理,如果扫描线离散化两次扫两遍其实也可以解决这个问题,但是这样无论在时间还是空间上稍微就有点浪费了啊.这里因为我是离散x坐标的所以对于平行于y轴的方向上的统计比较难统计.处理的方法是:标记区间左边的断点,和右边的断点,求出这个区间一共有多少个断点.就可以统计出平行于y轴的长度了.这里合并的时候需要判断右边的左区间和左边的右区间是否相同,如果相同的话,说明他们连接到了一起,要减去多加的. Picture Time Limit: 2000MS