51nod 1298 圓與三角形
阿新 • • 發佈:2017-12-31
ide 輸入 post names 點積 -- img mat 代碼
Input示例
給出圓的圓心和半徑,以及三角形的三個頂點,問圓同三角形是否相交。相交輸出"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"。
2 0 0 10 10 0 15 0 15 5 0 0 10 0 0 5 0 5 5Output示例
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(doubleView Codex1, 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 }
專業版:
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 圓與三角形