51nod 1298 圆与三角形

Posted 风子磊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod 1298 圆与三角形相关的知识,希望对你有一定的参考价值。

给出圆的圆心和半径,以及三角形的三个顶点,问圆同三角形是否相交。相交输出"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

分析:转化为求线段离圆心的最近和最远距离。最近距离小于等于r,最远距离大于等于r为相交。
普通版代码:
技术分享图片
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<math.h>
 4 #include<algorithm>
 5 #define LL long long
 6 using namespace std;
 7 double xc, yc, r;
 8 int pan(double x1, double y1, double x2, double y2)
 9 {
10     double d, d1, d2,maxd,mind;
11     d=fabs((xc-x1)*(y2-y1)-(yc-y1)*(x2-x1))/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));//点到直线距离
12     d1=sqrt((xc-x1)*(xc-x1)+(yc-y1)*(yc-y1));
13     d2=sqrt((xc-x2)*(xc-x2)+(yc-y2)*(yc-y2));//点到两个端点距离
14     if(((xc-x1)*(x2-x1)+(yc-y1)*(y2-y1))>0&&((xc-x2)*(x1-x2)+(yc-y2)*(y1-y2))>0)//判断点积大于0
15         mind=d;
16     else
17         mind=min(d1,d2);
18     maxd=max(d1,d2);
19     if(fabs(mind-r)<=1e-10||fabs(maxd-r)<=1e-10||(mind<r&&maxd>r))
20         return 1;
21     else
22         return 0;
23 }
24 int main()
25 {
26     int T;
27     double x1, y1, x2, y2, x3, y3, x, y;
28     scanf("%d", &T);
29     while(T--)
30     {
31         int f=0;
32         scanf("%lf%lf%lf", &xc, &yc, &r);
33         scanf("%lf%lf%lf%lf%lf%lf", &x1, &y1, &x2, &y2, &x3, &y3);
34         f=pan(x1,y1,x2,y2);
35         if(f==0)
36             f=pan(x1,y1,x3,y3);
37         if(f==0)
38             f=pan(x2,y2,x3,y3);
39         if(f==1)
40         printf("Yes\n");
41         else
42             printf("No\n");
43     }
44     return 0;
45 }
View Code

专业版:

技术分享图片
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<math.h>
 4 #include<algorithm>
 5 #define LL long long
 6 using namespace std;
 7 struct Point
 8 {
 9     double x, y;
10     Point(double x=0, double y=0):x(x),y(y){}
11 };
12 Point a[4];
13 double r;
14 typedef Point Vector;
15 Vector operator-(Point A, Point B){return Vector(A.x-B.x,A.y-B.y);}//向量
16 double Dot(Vector A, Vector B){return A.x*B.x+A.y*B.y;}//点积
17 double Length(Vector A){return sqrt(Dot(A,A));}//向量长度
18 double Cross(Vector A, Vector B){return A.x*B.y-A.y*B.x;}//叉积
19 int pan(Point A, Point B)
20 {
21     double d,d1,d2,maxd,mind;
22     d=fabs(Cross(a[0]-A,B-A))/Length(A-B);
23     d1=Length(a[0]-A);
24     d2=Length(a[0]-B);
25     if(Dot(a[0]-A,B-A)>0&&Dot(a[0]-B,A-B)>0)
26         mind=d;
27     else
28         mind=min(d1,d2);
29     maxd=max(d1,d2);
30     if(fabs(mind-r)<=1e-10||fabs(maxd-r)<=1e-10||(mind<r&&maxd>r))
31         return 1;
32     else
33         return 0;
34 }
35 int main()
36 {
37     int T;
38     scanf("%d", &T);
39     while(T--)
40     {
41         int f=0;
42         scanf("%lf%lf%lf", &a[0].x, &a[0].y, &r);
43         scanf("%lf%lf%lf%lf%lf%lf", &a[1].x, &a[1].y, &a[2].x, &a[2].y, &a[3].x, &a[3].y);
44         f=pan(a[1],a[2]);
45         if(f==0)
46             f=pan(a[1],a[3]);
47         if(f==0)
48             f=pan(a[2],a[3]);
49         if(f==1)
50         printf("Yes\n");
51         else
52             printf("No\n");
53     }
54     return 0;
55 }
View Code

 




以上是关于51nod 1298 圆与三角形的主要内容,如果未能解决你的问题,请参考以下文章

51nod-1298 圆与三角形

[51nod]1298 圆与三角形

51nod-1298 圆与三角形(计算几何超详解)

51nod 1298 圆与三角形

51Nod 1298 圆与三角形

51Nod 圆与三角形