51nod-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

/*
    data:2018.5.15
    author:gsw
    link:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1298
*/
#define ll long long
#define IO ios_with_sync(false);

#include<iostream>
#include<algorithm>
#include<cmath>
#include<stdio.h>
#include<string.h>
using namespace std;
class Point
{
    public:
        double x,y;
};
Point p1,p2,p3;
double xc,yc,r;

int disline(Point a,Point b,Point c,double R)
{//判断在圆外的两点形成的线段是否与圆相交
    if(c.x==b.x)
    {//bc线段与x轴垂直
        if(abs(a.x-b.x)>R)//圆心到bc直线的距离大于半径则不相交
            return 0;
        else
        {//圆心到bc直线的距离小于半径
            if((b.y>a.y&&c.y>a.y)||(b.y<a.y&&c.y<a.y))//若两点y均大于(小于)圆心的y则不相交
                return 0;
            else//其余情况均相交
                return 1;
        }
    }
    else if(c.y==b.y)
    {//bc线段与y轴垂直,原理同与x轴垂直
        if(abs(a.y-b.y)>R)
            return 0;
        else
        {
            if((b.x<a.x&&c.x<a.x)||(b.x>a.x&&c.x>a.x))
                return 0;
            else
                return 1;
        }
    }
    else
    {
        Point d;//bc直线上圆心r的垂点
        double kbc=(b.y-c.y)/(b.x-c.x);//根据公式y=kx+b,kbc为bc直线的k,bbc为其中的b,kad、bad同理
        double bbc=b.y-kbc*b.x;
        double kad=-1/kbc;
        double bad=a.y-kad*a.x;
        d.x=(bad-bbc)/(kbc-kad);
        d.y=kbc*d.x+bbc;
        if(((a.x-d.x)*(a.x-d.x)+(a.y-d.y)*(a.y-d.y))>r*r)//圆心到直线bc的距离大于半径则不相交
            return 0;
        else
        {//圆心到直线bc的距离小于半径
            if((d.x>b.x&&d.x>c.x)||(d.x<b.x&&d.x<c.x))//垂点d不在线段bc上则不相交
                return 0;
            else//其余情况则相交
                return 1;
        }
    }

}
bool judge()
{
    if(((p1.x-xc)*(p1.x-xc)+(p1.y-yc)*(p1.y-yc))<r*r&&
        ((p2.x-xc)*(p2.x-xc)+(p2.y-yc)*(p2.y-yc))<r*r&&
        ((p3.x-xc)*(p3.x-xc)+(p3.y-yc)*(p3.y-yc))<r*r)return false;
    if(((p1.x-xc)*(p1.x-xc)+(p1.y-yc)*(p1.y-yc))>r*r&&
        ((p2.x-xc)*(p2.x-xc)+(p2.y-yc)*(p2.y-yc))>r*r&&
        ((p3.x-xc)*(p3.x-xc)+(p3.y-yc)*(p3.y-yc))>r*r)
    {
        Point R;R.x=xc;R.y=yc;
        if(!disline(R,p1,p2,r) && !disline(R,p1,p3,r) && !disline(R,p2,p3,r))
            return false;
    }
    return true;
}

int main()
{
    int t;
    scanf("%d",&t);

    for(int i=0;i<t;i++)
    {
        cin>>xc>>yc>>r>>p1.x>>p1.y>>p2.x>>p2.y>>p3.x>>p3.y;
        if(judge())printf("Yes\n");//cout<<"Yes"<<endl;
        else printf("No\n");//cout<<"No"<<endl;


    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/fantastic123/p/9057934.html
今日推荐