51nod 1298 圆与三角形

51nod 1298 圆与三角形

这题我开始思考一下,应该关注三个点的情况。
情况应该如下:
1. 有点在圆上,那么肯定相交。
2. 有点在圆外,也有点在圆内,那么会相交。
结果wa了。
想简单了些,发现如果两点在圆外横跨圆也相交。。。

想来少一种情况考虑,
3. 三角形三点都在圆外,考虑边与圆是否相交,取两点和原点相连组成三角形,发现如果圆外面的角是钝角那么那条线段是不会交于圆的,直角也不会的,锐角的话呢,我们算其面积(用海伦公式),然后就能算出原点到边的距离,如果距离小于半径那么会相交,大家可以画图理解下。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
using namespace std;
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 510

int t;
double cx,cy,r;
double dist(double x1,double y1,double x2,double y2)
{
    double d=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    return d;
}

int line_pan(double x1,double y1,double x2,double y2)
{
    double a,b,c;
    a = dist(cx,cy,x1,y1);
    b = dist(cx,cy,x2,y2);
    c = dist(x1,y1,x2,y2);
    if((a+b) == c)
        return 1;
    if(a==b+c || b==a+c)
        return 0;
    if(a*a >= (b*b+c*c))
    {
        if(b <= r)
            return 1;
        else
            return 0;
    }
    if(b*b >= (a*a+c*c))
    {
        if(a<=r)
            return 1;
        else
            return 0;
    }
    double l=(a+b+c)/2;
    double s=sqrt(l*(l-a)*(l-b)*(l-c));
    double d=2*s/c;
    if(d <= r + 0.0001)
        return 1;
    else
        return 0;
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        double ans1,ans2,ans3;
        scanf("%lf%lf%lf",&cx,&cy,&r);
        double x1,y1;
        scanf("%lf%lf",&x1,&y1);
        ans1 = dist(x1,y1,cx,cy);
        double x2,y2;
        scanf("%lf%lf",&x2,&y2);
        ans2 = dist(x2,y2,cx,cy);
        double x3,y3;
        scanf("%lf%lf",&x3,&y3);
        ans3 = dist(x3,y3,cx,cy);
        if(ans1>r && ans2>r && ans3>r)
        {
            if(line_pan(x1,y1,x2,y2)||line_pan(x3,y3,x2,y2)||line_pan(x1,y1,x3,y3))
                printf("Yes\n");
            else
                printf("No\n");
        }
        else if(ans1<r && ans2<r && ans3<r)
            printf("No\n");
        else
            printf("Yes\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值