圆与三角形-51NOD 1298

来源:互联网 发布:java依赖注入 编辑:程序博客网 时间:2024/05/16 06:44

这几天又没怎么学习,懒癌末期啊真的是。
被一道圆与三角形的基础题难倒了,很烦,发现自己数学不好。
这个问题牵扯到线段和点的距离判断。
分三种情况
1. 点P到直线的距离等于点P到端点A的距离。
2. 点P到直线的距离等于点P到端点B的距离。
3. 点P到直线的距离等于点P到投影点C的距离。
设向量AP,向量AB。
AP与AB的余弦cos=AP·AB/|AP||AB|
若cos<0则是第一种情况了 我们return AP;
else 我们进行下一步运算
{
AC=AP*cos;
if(AC>AB)
return PB;
else
return PC;
}
然后找到圆心与三条边的最大值与最小值

if((max>r&&max<r)||max==r||min==r)就YES啊else就NO咯

然后悲剧地发现WA了
因为没有想到如果三条边与圆心的距离都小于r,但三个顶点与圆心的距离大于r的情况。
加进去,再交,再WA。
就很气。
检查数据之后发现这种几何题目需要加入精度控制。
于是又写了一个sgn

int sgn(double a){    return a<-eps?-1:a<eps?0:1;}

千辛万苦终于是AC了

//#define Debug#include <stdio.h>#include <math.h>#define MAXN 100001#define INF 0x3f3f3f3f#define MIN(a,b) a>b?b:a#define MAX(a,b) a>b?a:b#define eps 1e-6int cx,cy,r;int x[3],y[3];int sgn(double a){    return a<-eps?-1:a<eps?0:1;}double f(double a){    return a*a;}double point(int i){    return sqrt((x[i]-cx)*(x[i]-cx)+(y[i]-cy)*(y[i]-cy));}double line(int a,int b){    double apl=point(a),abl=sqrt(f(x[a]-x[b])+f(y[a]-y[b]));    double cos=((cx-x[a])*(x[b]-x[a])+(y[b]-y[a])*(cy-y[a]))/apl/abl;    if(cos<=0)    {        return apl;    }    else    {        double acl=apl*cos;        if(acl>abl)            return point(b);        else            return sqrt(f(apl)-f(acl));    }}int main(){#ifdef Debug    freopen("C:\\Users\\Yemor\\Desktop\\read.txt","r",stdin);#endif    int T;    double min,max,tmp;    scanf("%d",&T);    while(T--)    {        min=INF;        max=-INF;        scanf("%d%d%d",&cx,&cy,&r);        for (int i = 0; i < 3; ++i)        {            scanf("%d%d",&x[i],&y[i]);        }        for (int i = 0; i < 3; ++i)        {            tmp=point(i);            max=MAX(max,tmp);        }        for (int i = 0; i < 3; ++i)        {            if(i!=2)            {                tmp=line(i,i+1);            }            else            {                tmp=line(i,0);            }            min=MIN(min,tmp);            max=MAX(max,tmp);        }        if((sgn(max-r)>0&&sgn(min-r)<0)||sgn(max-r)==0||sgn(min-r)==0)            printf("%s\n","Yes" );        else            printf("%s\n","No" );    }    return 0;}
0 0
原创粉丝点击