zoukankan      html  css  js  c++  java
  • 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
    ");
    41         else
    42             printf("No
    ");
    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
    ");
    51         else
    52             printf("No
    ");
    53     }
    54     return 0;
    55 }
    View Code
  • 相关阅读:
    【背包问题】
    【CodeVS1037】取数游戏
    【CodeVS2226】飞行棋
    网线主管
    第一周计划
    毕业设计每日总结2020/2/16
    毕业设计每日总结2020/2/15
    毕业设计每日总结2020/2/14
    毕业设计每日总结2020/2/13
    毕业设计每日总结2020/2/12
  • 原文地址:https://www.cnblogs.com/zhulei2/p/8151101.html
Copyright © 2011-2022 走看看