您的位置:首页 > 其它

51Nod-1298 圆与三角形

2017-11-27 22:10 316 查看
1298 圆与三角形


题目来源: HackerRank

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题


 收藏


 关注

给出圆的圆心和半径,以及三角形的三个顶点,问圆同三角形是否相交。相交输出"Yes",否则输出"No"。(三角形的面积大于0)。





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


51Nod-1298 圆与三角形

思路:首先判断三角形的三个顶点与圆的关系:情况一:都在圆内,则不相交;情况二:都在圆外,则还需要另外处理,情况三:相交。

考虑情况二:判断两者相交,对三角形的三条边分别考虑,判断三角形的一条边是否与圆相交,首先判断边所在的直线是否与圆相交(可用圆心到直线的距离与其半径比较来判断),若相交再判断边与圆相交。

判断边与圆相交:在情况二的前提下,边与圆相交,则圆心必须在边的两个端点处于边垂直的两条直线之间所在的范围内,即圆心到边的中垂线的距离小于边的一半。因为边与圆相交,若圆心不在这个范围内,则这种情况就变成了情况一或情况三。

另一种直观的判断方法是判断边所在的直线与圆的交点是否在边上。

代码: 前一种判断方法。

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;

struct node{
double x;
double y;
}a[5];
int T;
double x0,y0,r;

bool f(node t1,node t2);
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
double x,y;
cin>>T;
while(T--){
int l=0;
cin>>x0>>y0>>r;
for(int i=0;i<3;++i)
{
cin>>x>>y;
a[i].x=x; a[i].y=y;
double d=pow(x-x0,2)+pow(y-y0,2);
if(d==r*r){
l=-5;
}else if(d>r*r)
l++;
}
if(l==0) puts("No");
else if(l==3){
if(f(a[0],a[1])||f(a[0],a[2])||f(a[1],a[2])){
puts("Yes");
} else puts("No");
}else puts("Yes");
}

return 0;
}

bool f(node t1,node t2)
{
double a1,b1,c1,a2,b2,c2;
double d1,d2;
double xx=(t1.x+t2.x)/2;
double yy=(t1.y+t2.y)/2;

a1=t2.y-t1.y; b1=t1.x-t2.x; c1=(t2.x-t1.x)*t1.y-(t2.y-t1.y)*t1.x;
d1=(a1*x0+b1*y0+c1)*(a1*x0+b1*y0+c1);
if(d1>r*r*(a1*a1+b1*b1)) return false;
a2=b1; b2=-a1; c2=-(a2*xx+b2*yy);
d2=(a2*x0+b2*y0+c2)*(a2*x0+b2*y0+c2);
int l=(t1.x-t2.x)*(t1.x-t2.x)+(t1.y-t2.y)*(t1.y-t2.y);
if(4*d2>l*(a2*a2+b2*b2)) return false;
return true;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: