51nod-1298-圆与三角(耐心,精度,耐心!)

题目链接

 问题:

给出圆的圆心和半径,以及三角形的三个顶点,

圆同三角形是否相交。相交输出"Yes",否则输出"No"。

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)

Input示例

2
0 0 10
10 0
15 0
15 5
0 0 10
0 0
5 0
5 5

Output示例

Yes
No

分析:

1.当三个点都在园内时,一定是NO

2.当三个点都在圆外时,判断 圆心到 线段的距离,这里需要分情况谈论

    判断圆心与线段构成的三角形

    如果圆外的两个角有一个是钝角,那么一定不相交

    如果都是锐角,可以用海伦公式求点到线段的距离

3.一定是YES,因为只剩下一种情况,既有圆内又有圆外的点

 

这里还卡了精度,!!!!!! 浮点数 比较,很烦人,

引入了 eps ~~~~~
 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>

using namespace std;

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) || b*b >= (a*a+c*c))
        return 0;

    // 圆外的角不是钝角的情况可以用海伦公式i
    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.00001) // 精度 问题
        return 1;
    else
        return 0;
}
int main()
{
    int t;
    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)
            printf("No\n");
        // 如果三点都在圆外
        else 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
            printf("Yes\n");
    }
    return 0;
}

           

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的体育馆管理系统,源码+数据库+毕业论文+视频演示 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本体育馆管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此体育馆管理系统利用当下成熟完善的SpringBoot框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进行程序开发。实现了用户在线选择试题并完成答题,在线查看考核分数。管理员管理收货地址管理、购物车管理、场地管理、场地订单管理、字典管理、赛事管理、赛事收藏管理、赛事评价管理、赛事订单管理、商品管理、商品收藏管理、商品评价管理、商品订单管理、用户管理、管理员管理等功能。体育馆管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 关键词:体育馆管理系统;SpringBoot框架;Mysql;自动化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值