HDU - 2948 Geometry Darts(计算几何 判断点在三角形 矩形 圆形内 典例)

题目大意:

       两个人比赛扔飞镖,现在有n个图形(圆,矩形,或三角形).他们进行k轮比赛,每轮比赛每人扔3次飞镖.一个飞镖的得分数等于该飞镖在多少个图形内.比较他们每轮的分数,输出他们每轮的比赛结果.

题解:

      判断点在三角形内:点和三角形各边构成的三角形的面积==原三角形面积

      判断点在圆形内:点和圆心的距离<=半径 

      判断点在矩形内:点坐标在对角顶点之间。即(x1<=x<=x2,y1<=y<=y2) 

     注意本题的精度,题目要求给的精度是1e-6,我就取了1e-7而看见网上有人说eps设为1e-10的话就错了,这是因为,如果你精度取得太高了,本来差在1e-7处的话,按照答案的判法应该正确而你却给判错了。

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <iostream>
#include<cmath>
using namespace std;
const double eps = 1e-7;
const double PI = acos(-1.0);

int dcmp(double x)
{
    if(fabs(x)<eps)
        return 0;
}
struct Point
{
    double x,y;
    Point() {}
    Point(double _x,double _y)
    {

        x = _x;
        y = _y;
    }
    bool operator == (Point b)const
    {
        return dcmp(x -b.x) == 0 && dcmp(y - b.y) == 0;
    }
    bool operator < (Point b)const
    {
        return dcmp(x - b.x)== 0?dcmp(y - b.y)<0:x<b.x;
    }
    Point operator - (const Point &b)const
    {
        return Point(x - b.x,y - b.y);
    }
//叉积
    double operator ^(const Point &b)const
    {
        return x*b.y - y*b.x;
    }
//点积
    double operator *(const Point &b)const
    {
        return x*b.x + y*b.y;
    }
//返回长度
    double len()
    {
        return hypot(x,y);//库函数
    }
//返回长度的平方
    double len2()
    {
        return x*x + y*y;
    }
//返回两点的距离
    double distance(Point p)
    {
        return hypot(x - p.x,y - p.y);
    }
    Point operator +(const Point &b)const
    {
        return Point(x+b.x,y+b.y);
    }
    Point operator *(const double &k)const
    {
        return Point(x*k,y*k);
    }
    Point operator /(const double &k)const
    {
        return Point(x/k,y/k);
    }
//计算 pa 和 pb 的夹角
//就是求这个点看 a,b 所成的夹角
//测试 LightOJ1203
    double rad(Point a,Point b)
    {
        Point p = *this;
        return fabs(atan2( fabs((a - p)^(b - p)),(a - p)*(b - p) ));
    }
//化为长度为 r 的向量
    Point trunc(double r)
    {
        double l = len();
        if(!dcmp(l))return *this;
        r /= l;
        return Point(x*r,y*r);
    }
//逆时针旋转 90 度
    Point rotleft()
    {
        return Point( - y,x);
    }
//顺时针旋转 90 度
    Point rotright()
    {
        return Point(y, - x);
    }
//绕着 p 点逆时针旋转 angle
    Point rotate(Point p,double angle)
    {
        Point v = (*this) - p;
        double c = cos(angle), s = sin(angle);
        return Point(p.x + v.x*c - v.y*s,p.y + v.x*s + v.y*c);
    }
};
struct Triangle
{
    Point A,B,C;
};
struct Circle
{
    Point p0;
    double r;
};
struct Rectangle
{
    Point A,B;
};

//判断点P是否在三角形ABC中
bool InTriangle(Point A,Point B,Point C,Point P)
{
    double Sabc = fabs((B-A)^(C-A));
    double Spab = fabs((A-P)^(B-P));
    double Spac = fabs((A-P)^(C-P));
    double Spbc = fabs((B-P)^(C-P));
    return dcmp(Sabc-Spab-Spac-Spbc)==0;
}
//判断点p是否在p0为圆心,r为半径的圆上
bool InCircle(Point p0,double r,Point p)
{
    double dis=sqrt((p.x-p0.x)*(p.x-p0.x)+(p.y-p0.y)*(p.y-p0.y));
    return dcmp(dis-r)<=0;
}
//判断P是否在A、B为对顶点的矩形上
bool InRectangle(Point A,Point B,Point P)
{
    return (dcmp(P.x-A.x)>=0 && dcmp(P.y-A.y)>=0 && dcmp(P.x-B.x)<=0 && dcmp(P.y-B.y)<=0);
}
vector<Triangle> tri;
vector<Circle> cir;
vector<Rectangle>rec;
int main()
{
    //freopen("input.txt","r",stdin);
    int T;
    cin>>T;
    while(T--)
    {
        char c;
        cin>>c;
        if(c=='C')
        {
            Circle t;
            cin>>t.p0.x>>t.p0.y>>t.r;
            cir.push_back(t);
        }
        if(c=='R')
        {
            Rectangle t;
            cin>>t.A.x>>t.A.y>>t.B.x>>t.B.y;
            rec.push_back(t);
        }
        if(c=='T')
        {
            Triangle t;
            cin>>t.A.x>>t.A.y>>t.B.x>>t.B.y>>t.C.x>>t.C.y;
            tri.push_back(t);
        }
    }
    cin>>T;
    while(T--)
    {
        Point tmp;
        int ans1=0,ans2=0;
        for(int i=1;i<=3;++i)
        {
            cin>>tmp.x>>tmp.y;
            for(int j=0;j<tri.size();++j)
                if(InTriangle(tri[j].A,tri[j].B,tri[j].C,tmp))
                    ++ans1;
            for(int j=0;j<rec.size();++j)
                if(InRectangle(rec[j].A,rec[j].B,tmp))
                    ++ans1;
            for(int j=0;j<cir.size();++j)
                if(InCircle(cir[j].p0,cir[j].r,tmp))
                    ++ans1;
        }
        for(int i=1;i<=3;++i)
        {
            cin>>tmp.x>>tmp.y;
            for(int j=0;j<tri.size();++j)
                if(InTriangle(tri[j].A,tri[j].B,tri[j].C,tmp))
                    ++ans2;
            for(int j=0;j<rec.size();++j)
                if(InRectangle(rec[j].A,rec[j].B,tmp))
                    ++ans2;
            for(int j=0;j<cir.size();++j)
                if(InCircle(cir[j].p0,cir[j].r,tmp))
                    ++ans2;
        }
        if(ans1==ans2)
            puts("Tied");
        else if(ans1>ans2)
                puts("Bob");
        else puts("Hannah");
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值