1. 程式人生 > >51nod 1298 圓與三角形

51nod 1298 圓與三角形

ide 輸入 post names 點積 -- img mat 代碼

給出圓的圓心和半徑,以及三角形的三個頂點,問圓同三角形是否相交。相交輸出"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 圓與三角形