给出圆的圆心和半径,以及三角形的三个顶点,问圆同三角形是否相交。相交输出"Yes",否则输出"No"。(三角形的面积大于0)。
![](http://img.51nod.com/upfile/000fbd56/08d1bc4455418997000000000000000c.jpeg)
![](http://img.51nod.com/upfile/000fbd56/08d1bc445a06ab83000000000000000d.jpeg)
Input
第1行:一个数T,表示输入的测试数量(1 <= T <= 10000),之后每4行用来描述一组测试数据。 4-1:三个数,前两个数为圆心的坐标xc, yc,第3个数为圆的半径R。(-3000 <= xc, yc <= 3000, 1 <= R <= 3000) 4-2:2个数,三角形第1个点的坐标。 4-3:2个数,三角形第2个点的坐标。 4-4:2个数,三角形第3个点的坐标。(-3000 <= xi, yi <= 3000)
Output
共T行,对于每组输入数据,相交输出"Yes",否则输出"No"。
Input示例
2 0 0 10 10 0 15 0 15 5 0 0 10 0 0 5 0 5 5
Output示例
Yes No
题目思路:有三种情况:
1.三点全在圆内,一定不相交
2.三点有点在圆内,有点在圆外,一定相交
3.三点全在圆外,有可能相交,要判断圆心到边是否有垂线,有垂线且长度小于半径则在圆内
代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> using namespace std; struct point{ double x,y; }o,a,b,c; double d(point a,point b)//两点距离的平方 { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } int main() { int t; double r; cin>>t; while(t--) { int flag=0,flag1=0,flag2=0; cin>>o.x>>o.y>>r; cin>>a.x>>a.y; cin>>b.x>>b.y; cin>>c.x>>c.y; if(d(a,o)>=r*r||d(b,o)>=r*r||d(c,o)>=r*r)//点是否在圆外 flag1=1; if(d(a,o)<=r*r||d(b,o)<=r*r||d(c,o)<=r*r)//点是否在圆内 flag2=1; if(flag1&&flag2)//有点在圆内也有在圆外必定相交 flag=1; else if(flag1&&!flag2)//点全在员外 { double a1,b1,c1,ab,ac,bc,s; a1=d(a,o); b1=d(b,o); c1=d(c,o); ab=d(a,b); ac=d(a,c); bc=d(b,c); if(a1+ab>=b1&&b1+ab>=a1)//判断是否有垂线 { s=ab*a1-((ab+a1-b1)/2*(ab+a1-b1)/2);//秦九韶公式 if(sqrt(s/ab)<=r) flag=1; } if(a1+ac>=c1&&c1+ac>=a1) { s=ac*a1-((ac+a1-c1)/2*(ac+a1-c1)/2); if(sqrt(s/ac)<=r) flag=1; } if(b1+bc>=c1&&c1+bc>=b1) { s=bc*b1-((bc+b1-c1)/2*(bc+b1-c1)/2); if(sqrt(s/bc)<=r) flag=1; } } if(flag) cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }