HDU 4720 Naive and Silly Muggles(计算几何)

题目链接:点击打开链接

题目大意:要求给的目标点在题目给的3点组成的圆圈之外才算safe,否则为danger

题目分析:第一反映为外接圆,但是仔细一想就没必要。比如钝角三角形最大角的顶点就没必要在圆上;自然就先判断是否为钝角或则直角,方法为先找最大边,因为最大边对应  

                   的为最大角。直接判断这个角是否为钝角就行。如果为钝角,则圆心就是最长边的中点。否则就是利用公式推导

题目总结:1.变量名不能太“正”了,比如disitance,出现

error:no type named iterator_category in struct

一个非常诡异的错误,我只是写了一段普通的代码,却爆出来一大堆STL相关的错误信息(STL的错误信息实在是太难看了)。后来仔细研究发现,是函数命名存在问题。猛然想起distance是STL中求迭代器距离的一个函数,这里冲突了。

                    2.当心函数没有返回值,就随机返回一个值

                    3.关于已知3个点计算外接三角形的圆心,其实没有什么高端的,就是硬算,圆心到3点的距离都相等然后化简:

                   设
                   P1(X1,Y1)、P2(X2,Y2)、P3(X3,Y3)

                   A=x1^2+Y1^2;B=x2^2+Y2^2;

                   C=X3^2+Y3^2;

                   G=(Y3-Y2)*X1+(Y1-Y3)*X2+(Y2-Y1)*X3

                   X=((B-C)*Y1+(C-A)*Y2+(A-B)*Y3)/(2*G)

                   Y=((C-B)*X1+(A-C)*X2+(B-A)*X3)/(2*G)

                  4.向量数量级判断角钝锐,x1*x2+y1*y2>0 ,为锐角;


#include<functional>
#include<algorithm>
#include<iostream>
#include<fstream>
#include<sstream>
#include<iomanip>
#include<numeric>
#include<cstring>
#include<climits>
#include<cassert>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<list>
#include<set>
#include<map>
using namespace std;
struct point
{
    double x,y;
    point(double x1=0,double y1=0)
    {
        x=x1;
        y=y1;
    }
    point operator -(const point &b)const
    {
        return point(x-b.x,y-b.y);
    }
    double operator &(const point &b) const
    {
       return x*b.x+y*b.y ;
    }

} p[5];

point find_o(point p1,point p2,point p3)
{
    double a,b,c,tmp;
    point ans;
    a=p1.x*p1.x+p1.y*p1.y , b=p2.x*p2.x+p2.y*p2.y , c=p3.x*p3.x+p3.y*p3.y;
    tmp=(p3.y-p2.y)*p1.x+(p1.y-p3.y)*p2.x+(p2.y-p1.y)*p3.x;
    ans.x=((b-c)*p1.y+(c-a)*p2.y+(a-b)*p3.y)/(2*tmp);
    ans.y=((c-b)*p1.x+(a-c)*p2.x+(b-a)*p3.x)/(2*tmp);
    return ans;
}
double distanc(point p1,point p2)
{
    double ans=(p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y);
    return ans;
}
int is_dun(point p1,point p2,point p3)
{
    double a=distanc(p1,p2),b=distanc(p3,p2),c=distanc(p3,p1);

    if(a>=b&& a >=c)
    {
        if(((p1-p3)&(p2-p3))>0)
        return 0;
        p[4].x=fabs(p1.x-p2.x)/2;
        p[4].y=fabs(p1.y-p2.y)/2;return 1;
    }
   else if(c>=b&&c>=a)
    {
        if(((p1-p2)&(p3-p2))>0)
        return 0;
        p[4].x=fabs(p1.x-p3.x)/2;
        p[4].y=fabs(p1.y-p3.y)/2;return 1;
    }
    else if(b>=c&&b>=a)
    {
        if(((p2-p1)&(p3-p1))>0)
        return 0;
        p[4].x=fabs(p2.x-p3.x)/2;
        p[4].y=fabs(p2.y-p3.y)/2;return 1;
    }

}
main()
{
    int t,tt=1;
    double edge,edge2;
    scanf("%d",&t);
    while(t--)
    {
       for(int i=0;i<4;i++) scanf("%lf %lf",&p[i].x,&p[i].y);
       if(!is_dun(p[0],p[1],p[2]))
         p[4]= find_o ( p[0],p[1],p[2] );
       edge=distanc(p[0],p[4]);
       edge2=distanc(p[3],p[4]);
       printf("Case #%d: ",tt++);
       if(edge<edge2) printf("Safe\n");
       else printf("Danger\n");
    }
    return 0;
}

         

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值