题目大意:
两个人比赛扔飞镖,现在有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;
}