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) push_back(a)
#define mem(i,j) memset(i,j,sizeof(i))
const int N=1e5+;
const int MOD=1e9+;
const double eps=1e-; double add(double a,double b) {
if(abs(a+b)<eps*(abs(a)+abs(b))) return ;
return a+b;
}
int dcmp(double x) {
if(abs(x)<eps) return ;
else return x< ? -:;
}
struct P {
double x,y;
P(){} P(double _x,double _y):x(_x),y(_y){}
P operator - (P p) { return P(add(x,-p.x),add(y,-p.y)); }
P operator + (P p) { return P(add(x,p.x),add(y,p.y)); }
P operator * (double d) { return P(x*d,y*d); }
P operator / (double d) { return P(x/d,y/d); }
double dot (P p) { return add(x*p.x,y*p.y); }
double det (P p) { return add(x*p.y,-y*p.x); }
bool operator == (const P& p)const {
return abs(x-p.x)<eps && abs(y-p.y)<eps; }
bool operator < (const P& p)const {
return x<p.x || (x==p.x && y<p.y); }
};
struct L {
P p, v; double ang;
L(){} L(P _p,P _v):p(_p),v(_v){ ang=atan2(v.y,v.x); }
P acP(double t) { return p+v*t; }
};
struct C {
P p; double r;
C(){} C(P _p,double _r):p(_p),r(_r){}
P acP(double a) { return P(p.x+cos(a)*r,p.y+sin(a)*r); }
double AL(double ang) { return ang*r; }
}c;
// 求向量a的长度
double lenP(P a) { return sqrt(a.dot(a)); }
// 求向量v极角
double angle(P v) { return atan2(v.y,v.x); }
// 求两向量夹角
double Angle(P u,P v) { return acos(u.dot(v)/lenP(u)/lenP(v));}
/* 判断两圆相交
求圆c1与c2的交点 并用s保存交点
w记录是外切1还是内切-1
*/
int insCC(C c1,C c2,vector<P>& s,int* w) {
double d=lenP(c1.p-c2.p);
if(abs(d)<eps) {
if(abs(c1.r-c2.r)<eps) return -; // 重合
return ; // 内含
}
if((c1.r+c2.r-d)<-eps) return ; // 外离
if(d-abs(c1.r-c2.r)<-eps) return ; // 内离 (*w)=dcmp(d-c1.r);
double ang=angle(c2.p-c1.p); // 向量c1c2求极角
double da=acos((c1.r*c1.r+d*d-c2.r*c2.r)/(*c1.r*d));
// c1与交点的向量 与 c1c2 的夹角
P p1=c1.acP(ang-da), p2=c1.acP(ang+da); // 求得两交点 s.pb(p1);
if(p1==p2) return ; // 同一个点
s.pb(p2); return ;
} int main()
{
int t; scanf("%d",&t);
while(t--) {
int m; double r;
scanf("%d%lf",&m,&r);
c.p.x=c.p.y=, c.r=r;
double ans=2.0*PI*c.r;
while(m--) {
//printf("%lf\n",ans);
C t; scanf("%lf%lf%lf",&t.p.x,&t.p.y,&t.r);
vector <P> p; p.clear();
int w, s=insCC(c,t,p,&w);
if(s==) {
if(w==-) ans+=2.0*PI*t.r;
} else if(s==) {
P u=p[], v=p[];
double ang=Angle(u,v);
if(dcmp(u.det(v))<) ang=2.0*PI-ang;
ans-=c.AL(ang); /// 减去圆盘被切的部分周长
u=p[]-t.p, v=p[]-t.p;
ang=Angle(u,v);
if(dcmp(u.det(v))>) ang=2.0*PI-ang;
ans+=t.AL(ang); /// 加上切割产生的新边缘
}
}
printf("%.10f\n",ans);
} return ;
}
也可以用余弦定理 https://www.cnblogs.com/Dillonh/p/9433714.html
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long
#define PI acos(-1)
#define pb(a) push_back(a)
#define mem(i,j) memset(i,j,sizeof(i))
const int N=1e5+;
const int MOD=1e9+;
const double eps=1e-; double add(double a,double b) {
if(abs(a+b)<eps*(abs(a)+abs(b))) return ;
return a+b;
}
int dcmp(double x) {
if(abs(x)<eps) return ;
else return x< ? -:;
}
struct P {
double x,y;
P(){} P(double _x,double _y):x(_x),y(_y){}
P operator - (P p) { return P(add(x,-p.x),add(y,-p.y)); }
P operator + (P p) { return P(add(x,p.x),add(y,p.y)); }
P operator * (double d) { return P(x*d,y*d); }
P operator / (double d) { return P(x/d,y/d); }
double dot (P p) { return add(x*p.x,y*p.y); }
double det (P p) { return add(x*p.y,-y*p.x); }
bool operator == (const P& p)const {
return abs(x-p.x)<eps && abs(y-p.y)<eps; }
bool operator < (const P& p)const {
return x<p.x || (x==p.x && y<p.y); }
};
struct C {
P p; double r;
C(){} C(P _p,double _r):p(_p),r(_r){}
P acP(double a) { return P(p.x+cos(a)*r,p.y+sin(a)*r); }
double AL(double ang) { return ang*r; }
}c;
// 求向量a的长度
double lenP(P a) { return sqrt(a.dot(a)); }
double change(C t) {
double D=lenP(t.p);
if(dcmp(c.r-t.r-D)>) return ; // 内离
if(dcmp(c.r-t.r-D)==) return 2.0*PI*t.r; // 内切
if(dcmp(c.r+t.r-D)<=) return ; // 外离 外切
double angc=acos((c.r*c.r+D*D-t.r*t.r)/(2.0*c.r*D));
double angt=acos((t.r*t.r+D*D-c.r*c.r)/(2.0*t.r*D));
return t.AL(angt*2.0)-c.AL(angc*2.0);
} int main()
{
int t; scanf("%d",&t);
while(t--) {
int m; double r;
scanf("%d%lf",&m,&r);
c.p.x=c.p.y=, c.r=r;
double ans=2.0*PI*c.r;
while(m--) {
C t; scanf("%lf%lf%lf",&t.p.x,&t.p.y,&t.r);
ans+=change(t);
}
printf("%.10f\n",ans);
} return ;
}
hdu6354 /// 圆的相交的更多相关文章
- hdu6354 Everything Has Changed (圆的相交弧长)
题目传送门 题意: 用一堆圆来切割一个圆心为原点,半径为R的圆A,问切割完毕后圆A外围剩余部分的周长(图中的红线部分). 思路: 首先判定圆与圆A的关系,这题我们只需要与A内切.相交的圆. 然后就是求 ...
- codeforce gym/100495/problem/K—Wolf and sheep 两圆求相交面积 与 gym/100495/problem/E—Simple sequence思路简述
之前几乎没写过什么这种几何的计算题.在众多大佬的博客下终于记起来了当时的公式.嘚赶快补计算几何和概率论的坑了... 这题的要求,在对两圆相交的板子略做修改后,很容易实现.这里直接给出代码.重点的部分有 ...
- Everything Has Changed(HDU6354+圆交+求周长)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6354 题目: 题意:用一堆圆来切割一个圆心为原点,半径为R的圆A,问切割完毕后圆A外围剩余部分的周长( ...
- hdu1174(3维射线与圆是否相交)
简单的题意,要注意z2 = h2*0.9-r2 #include <iostream> #include <cmath> #include <vector> #in ...
- 多边形和圆的相交面积(模板)hdu2892、hdu4404
area Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- HDU 3467 (求五个圆相交面积) Song of the Siren
还没开始写题解我就已经内牛满面了,从晚饭搞到现在,WA得我都快哭了呢 题意: 在DotA中,你现在1V5,但是你的英雄有一个半径为r的眩晕技能,已知敌方五个英雄的坐标,问能否将该技能投放到一个合适的位 ...
- HDU 3264 Open-air shopping malls (计算几何-圆相交面积)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=3264 题意:给你n个圆,坐标和半径,然后要在这n个圆的圆心画一个大圆,大圆与这n个圆相交的面积必须大于等 ...
- CodeForces 8D Two Friends 判断三个圆相交
题意: 有两个人\(Alan\)和\(Bob\),他们现在都在\(A\)点,现在\(Bob\)想去\(B\)点,\(Alan\)想先到\(C\)点再去\(B\)点. \(Alan\)所走的总路程不能超 ...
- hdu5858 Hard problem(求两圆相交面积)
题目传送门 Hard problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Other ...
随机推荐
- 使用postman做接口测试----柠檬不萌!
目录 一.GET和POST请求的区别 二.http协议 1.http请求分为两个部分 2.http状态码 三.使用postman测试HTTP接口 1.请求方式:get 2.请求方式:post 3.请求 ...
- 浅析Draw Call
Draw Call是CPU对GPU的一种命令,仅仅指向一个需要被渲染的图元列表,在OpenGL和DirectX中分别体现为glDrawElements和DrawIndexedPrimitive图像编程 ...
- spring配置mybatis的sqlsessionfactory
<!--读入配置文件 --> <bean id="propertyConfigurer" class="org.springframework.bean ...
- leetcode.位运算.136只出现一次的元素-Java
1. 具体题目 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明:你的算法应该具有线性时间复杂度. 你可以不使用额外空间来实现吗? 示例 1 ...
- CTU OPEN 2017 Shooting Gallery /// 区间DP
题目大意: 给定n 给定n个数 选定一个区间留下其他消去 要求区间两端的两个数一样 若成功留下一个区间 则在选定区间的基础上 继续进行上述操作 直到无法再选出这样的区间 求最多操作数 按区间长度由短到 ...
- 桩服务开发2---与python结合
from mitmproxy import httpdef request(flow): request_data=flow.request print(request_data) 进入py目录,在终 ...
- 【学术篇】CF932E Team Work && bzoj5093 图的价值
两个题的传送门 对于CF这道题, 分别考虑每种可能的集合大小, 每个大小为\(k\)的集合数量有\(\binom nk\)个, 所以最后的答案就是 \[\sum_{i=0}^n\binom{n}{i} ...
- Codeforces 1140F 线段树 分治 并查集
题意及思路:https://blog.csdn.net/u013534123/article/details/89010251 之前cf有一个和这个相似的题,不过那个题只有合并操作,没有删除操作,直接 ...
- 解决ubuntu终端路劲显示过长问题
1 找到配置文件先进行备份: cp ~/.bashrc ~/.bashrc-bak 2 找到配置文件修改: vi ~/.bashrc 备份是为了防止配置修改出错,可以还原 3 在以下的红色位置 ...
- 3、Python 基础类型 -- List 列表类型
2.更新列表:list.append() 3.删除列表元素 del