bjfu1235 两圆公共面积
给定两个圆,求其覆盖的面积,其实也就是求其公共面积(然后用两圆面积和减去此值即得最后结果)。
我一开始是用计算几何的方法做的,结果始终不过。代码如下:
/*
* Author : ben
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <functional>
#include <numeric>
#include <cctype>
using namespace std;
const double pi = acos(-);
typedef struct MyPoint {
double x, y;
MyPoint(double xx = , double yy = ) {
x = xx;
y = yy;
}
} MyPoint; inline double mydistance2(const MyPoint &p1, const MyPoint &p2) {
return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y);
} inline double mydistance(const MyPoint &p1, const MyPoint &p2) {
return sqrt(mydistance2(p1, p2));
} MyPoint intersection(MyPoint u1, MyPoint u2, MyPoint v1, MyPoint v2) {
MyPoint ret = u1;
double t = ((u1.x - v1.x) * (v1.y - v2.y) - (u1.y - v1.y) * (v1.x - v2.x))
/ ((u1.x - u2.x) * (v1.y - v2.y) - (u1.y - u2.y) * (v1.x - v2.x));
ret.x += (u2.x - u1.x) * t;
ret.y += (u2.y - u1.y) * t;
return ret;
} void intersection_line_circle(MyPoint c, double r, MyPoint l1, MyPoint l2,
MyPoint& p1, MyPoint& p2) {
MyPoint p = c;
double t;
p.x += l1.y - l2.y;
p.y += l2.x - l1.x;
p = intersection(p, c, l1, l2);
t = sqrt(r * r - mydistance(p, c) * mydistance(p, c)) / mydistance(l1, l2);
p1.x = p.x + (l2.x - l1.x) * t;
p1.y = p.y + (l2.y - l1.y) * t;
p2.x = p.x - (l2.x - l1.x) * t;
p2.y = p.y - (l2.y - l1.y) * t;
} void intersection_circle_circle(MyPoint c1, double r1, MyPoint c2, double r2,
MyPoint& p1, MyPoint& p2) {
MyPoint u, v;
double t;
t = ( + (r1 * r1 - r2 * r2) / mydistance(c1, c2) / mydistance(c1, c2)) / ;
u.x = c1.x + (c2.x - c1.x) * t;
u.y = c1.y + (c2.y - c1.y) * t;
v.x = u.x + c1.y - c2.y;
v.y = u.y - c1.x + c2.x;
intersection_line_circle(c1, r1, u, v, p1, p2);
} int main() {
freopen("data.in", "r", stdin);
// freopen("data.out", "w", stdout);
int T;
double x, y, r1, r2;
scanf("%d", &T);
double ans;
while (T--) {
scanf("%lf%lf%lf", &x, &y, &r1);
MyPoint c1(x, y);
scanf("%lf%lf%lf", &x, &y, &r2);
MyPoint c2(x, y);
double dis2 = mydistance2(c1, c2);
double dis = sqrt(dis2);
if (dis >= r1 + r2) { //相离
ans = pi * r1 * r1 + pi * r2 * r2;
} else if (dis <= fabs(r1 - r2)) { //包含
double r = r1 > r2 ? r1 : r2;
ans = pi * r * r;
} else { //相交
MyPoint p1, p2;
intersection_circle_circle(c1, r1, c2, r2, p1, p2);
double d2 = mydistance(p1, p2) / ;
double angle1 = asin(d2 / r1);
double angle2 = asin(d2 / r2);
double Sanjiao1 = sqrt(r1 * r1 - d2 * d2) * d2;
double Sanjiao2 = sqrt(r2 * r2 - d2 * d2) * d2;
double San1 = r1 * r1 * angle1;
double San2 = r2 * r2 * angle2;
ans = pi * r1 * r1 + pi * r2 * r2;
ans -= San1 + San2 - Sanjiao1 - Sanjiao2;
}
printf("%.6f\n", ans);
}
return ;
}
根据后来的调试,应该是对如下图b的情况处理不正确。
于是后来上网找了几个中学的解析几何公式,终于a了。
做法是联立两个圆的方程(相减),得到相交弦所在直线方程,然后用点到直接的距离公式得到h1和h2,接着算出θ1和θ2,然后就能求得三角形的面积和扇形的面积了。一开始我以为需要分类讨论上面图a和图b两种情况,后来发现,直接去掉求距离时的取绝对值运算就可以了,因为距离为负的时候,得到的夹角也是负的,这样求的三角形面积是负的,扇形也是原先的相补的那部分,具体的图我就不画了,很容易想明白的。
AC代码如下:
/*
* Author : ben
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <functional>
#include <numeric>
#include <cctype>
using namespace std;
const double pi = acos(-);
typedef struct MyPoint {
double x, y;
MyPoint(double xx = , double yy = ) {
x = xx;
y = yy;
}
} MyPoint; inline double mydistance2(const MyPoint &p1, const MyPoint &p2) {
return (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y);
} int main() {
// freopen("data.in", "r", stdin);
int T;
scanf("%d", &T);
double ans, r1, r2;
MyPoint c1, c2;
while (T--) {
scanf("%lf%lf%lf", &c1.x, &c1.y, &r1);
scanf("%lf%lf%lf", &c2.x, &c2.y, &r2);
double dis2 = mydistance2(c1, c2);
double dis = sqrt(dis2);
if (dis >= r1 + r2) { //相离
ans = pi * r1 * r1 + pi * r2 * r2;
} else if (dis <= fabs(r1 - r2)) { //包含
double r = r1 > r2 ? r1 : r2;
ans = pi * r * r;
} else { //相交
//h1和h2可能为负
double h1 = (dis2 + r1 * r1 - r2 * r2) / dis / 2.0;
double h2 = dis - h1;
double angle1 = acos(h1 / r1);
double angle2 = acos(h2 / r2);
double Sanjiao = sqrt(r1 * r1 - h1 * h1) * dis;
double Sanxin1 = r1 * r1 * angle1;
double Sanxin2 = r2 * r2 * angle2;
ans = pi * r1 * r1 + pi * r2 * r2;
ans -= Sanxin1 + Sanxin2 - Sanjiao;
}
printf("%.6f\n", ans);
}
return ;
}
bjfu1235 两圆公共面积的更多相关文章
- poj 2546(两圆公共面积)
Circular Area Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5682 Accepted: 2225 Des ...
- poj2546Circular Area(两圆相交面积)
链接 画图推公式 这两种情况 都可用一种公式算出来 就是两圆都求出圆心角 求出扇形的面积减掉三角形面积 #include <iostream> using namespace std; # ...
- [hdu 3264] Open-air shopping malls(二分+两圆相交面积)
题目大意是:先给你一些圆,你可以任选这些圆中的一个圆点作圆,这个圆的要求是:你画完以后.这个圆要可以覆盖之前给出的每一个圆一半以上的面积,即覆盖1/2以上每一个圆的面积. 比如例子数据,选左边还是选右 ...
- hdu5858 Hard problem(求两圆相交面积)
题目传送门 Hard problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Other ...
- hdu 3264(枚举+二分+圆的公共面积)
Open-air shopping malls Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- codeforce gym/100495/problem/K—Wolf and sheep 两圆求相交面积 与 gym/100495/problem/E—Simple sequence思路简述
之前几乎没写过什么这种几何的计算题.在众多大佬的博客下终于记起来了当时的公式.嘚赶快补计算几何和概率论的坑了... 这题的要求,在对两圆相交的板子略做修改后,很容易实现.这里直接给出代码.重点的部分有 ...
- POJ 2546 & ZOJ 1597 Circular Area(求两圆相交的面积 模板)
题目链接: POJ:http://poj.org/problem? id=2546 ZOJ:problemId=597" target="_blank">http: ...
- 求两圆相交部分面积(C++)
已知两圆圆心坐标和半径,求相交部分面积: #include <iostream> using namespace std; #include<cmath> #include&l ...
- 简单几何(圆与多边形公共面积) UVALive 7072 Signal Interference (14广州D)
题目传送门 题意:一个多边形,A点和B点,满足PB <= k * PA的P的范围与多边形的公共面积. 分析:这是个阿波罗尼斯圆.既然是圆,那么设圆的一般方程:(x + D/2) ^ 2 + (y ...
随机推荐
- Android 近百个项目的源代码
Android 近百个项目的源代码 Android PDF 阅读器 http://sourceforge.net/projects/andpdf/files/个人记账工具 OnMyMeans http ...
- hadoop:could only be replicated to 0 nodes, instead of 1
在Hadoop的环境搭建过程中,常常会遇到类似这样的错误信息提示:“could only be replicated to 0 nodes, instead of 1 ”,产生这样的错误原因有多种,这 ...
- Intellij 导入play framework 项目
新建一个项目 play new helloworld IshallbeThatIshallbe:~ iamthat$ mkdir temp IshallbeThatIshallbe:~ iamthat ...
- spring autoWire注解
1.autowire注解,可以用来获得applicationContext,ResourceLoader,BeanFactory的注入 autoWire会获得相应资源 2.autoWire注解还可以用 ...
- DelphiXE下String转PAnsiChar(反向转换)
很多资料只提到升迁到xe,而我们调用底版本c++开发的程序,是只能按Ansi操作的,所以需要反向转换. var s:PansiChar;s:=PansiChar(AnsiString('我我我我我') ...
- Java IDE 编辑器 --- IntelliJ IDEA 进阶篇 生成 hibernate 实体与映射文件
原文:转:Java IDE 编辑器 --- IntelliJ IDEA 进阶篇 生成 hibernate 实体与映射文件 2011-04-30 12:50 很多人不知道怎么用 IntelliJ IDE ...
- iOS iOS7越狱
1.使用盘古越狱工具 (或者PP助手) 2.越狱成功后需要安装Apple File Conduit “2”,用于替代afc2add插件 3.安装AppSync插件 (绕过系统验证,随意安装.运行破解的 ...
- 喵星人教你记 HTTP 状态码
记忆HTTP状态码是有一些困难的,因为状态码很多且很难记忆.GirlieMac,也就是Tomomi Imura利用她巧妙的构思,PS了一系列的HTTP状态信息.在你看过这些图片之后,你绝对可以记住一些 ...
- 243. Shortest Word Distance
题目: Given a list of words and two words word1 and word2, return the shortest distance between these ...
- 10个提供免费PHP脚本下载的网站
本文将重点介绍10个PHP脚本的免费资源下载站.之前推荐 <16个下载超酷脚本的热门网站>,这些网站除了PHP脚本,还有JavaScript.Java.Perl.ASP等脚本.如果你已是脚 ...