HDU 2948 Geometry Darts(点在圆,三角形,矩形内判定)
http://acm.hdu.edu.cn/showproblem.php?pid=2948
题意:
两个人比赛扔飞镖,现在有n个图形(圆,矩形,或三角形).他们进行k轮比赛,每轮比赛每人扔3次飞镖.一个飞镖的得分数等于该飞镖在多少个图形内.比较他们每轮的分数,输出他们每轮的比赛结果.
分析:
本题本质就是判断一个给定点是否在圆或矩形或三角形内.
判断点在圆内,只要看点到圆形的距离是否<=圆半径.
判断点在矩形内,只要看点坐标输入[x1,x2]和[y1,y2]范围.
判断点在三角形内,只要看点与三角形各边构成三角形的面积是否==三角形总面积.
之后比较二者得分即可.
注意:开始我精度eps取1e-10,直接WA.改成1e-6就对了.
用了vector容器,C++提交险些超时…g++提交没问题.
AC代码:
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const double eps=1e-6;//如果取1e-10就会WA
int dcmp(double x)
{
if(fabs(x)<eps) return 0;
return x<0?-1:1;
}
struct Point
{
double x,y;
Point(){}
Point(double x,double y):x(x),y(y){}
};
typedef Point Vector;
Vector operator-(Point A,Point B)
{
return Vector(A.x-B.x,A.y-B.y);
}
double Cross(Vector A,Vector B)
{
return A.x*B.y-A.y*B.x;
}
/***以上为刘汝佳模板***/
struct Circle
{
double x,y,r;
bool InCircle(Point p)
{
double dist=(p.x-x)*(p.x-x)+(p.y-y)*(p.y-y);
return dcmp(r*r-dist)>=0;
}
};
struct Rectangle
{
double x1,y1,x2,y2;
bool InRectangle(Point p)
{
return dcmp(p.x-x2)<=0&&dcmp(p.x-x1)>=0&&dcmp(p.y-y2)<=0&&dcmp(p.y-y1)>=0;
}
};
struct Triangle
{
Point p[3];
bool InTriangle(Point P)
{
double a1=fabs(Cross(P-p[0],p[0]-p[1]));
double a2=fabs(Cross(P-p[1],p[1]-p[2]));
double a3=fabs(Cross(P-p[2],p[2]-p[0]));
double area=fabs(Cross(p[0]-p[1],p[1]-p[2]));
return dcmp(a1+a2+a3-area)==0;
}
};
vector<Circle> C;
vector<Rectangle> R;
vector<Triangle> T;
int main()
{
int n,m;
while(scanf("%d",&n)==1)
{
C.clear(),T.clear(),R.clear();
for(int i=1;i<=n;++i)
{
char type;
scanf(" %c",&type);
if(type=='C')
{
Circle c1;
scanf("%lf%lf%lf",&c1.x,&c1.y,&c1.r);
C.push_back(c1);
}
else if(type=='R')
{
Rectangle r1;
scanf("%lf%lf%lf%lf",&r1.x1,&r1.y1,&r1.x2,&r1.y2);
R.push_back(r1);
}
else if(type=='T')
{
Triangle t1;
for(int i=0;i<3;++i) scanf("%lf%lf",&t1.p[i].x,&t1.p[i].y);
T.push_back(t1);
}
}
scanf("%d",&m);
while(m--)
{
int s1=0,s2=0;//两边的分数
for(int i=0;i<3;i++)
{
Point p;
scanf("%lf%lf",&p.x,&p.y);
for(int j=0;j<C.size();++j)
if(C[j].InCircle(p)) s1++;
for(int j=0;j<R.size();++j)
if(R[j].InRectangle(p)) s1++;
for(int j=0;j<T.size();++j)
if(T[j].InTriangle(p)) s1++;
}
for(int i=0;i<3;i++)
{
Point p;
scanf("%lf%lf",&p.x,&p.y);
for(int j=0;j<C.size();++j)
if(C[j].InCircle(p)) s2++;
for(int j=0;j<R.size();++j)
if(R[j].InRectangle(p)) s2++;
for(int j=0;j<T.size();++j)
if(T[j].InTriangle(p)) s2++;
}
if(s1==s2) printf("Tied\n");
else printf("%s\n",s1>s2?"Bob":"Hannah");
}
}
return 0;
}
分享到:
相关推荐
HDU的1250,主要是利用高精度加法,但是代码有点繁琐,效率不是很高
杭电ACMhdu1163
HDU1059的代码
hdu1001解题报告
hdu 1574 passed sorce
HDU的一题........HDU DP动态规
hdu acm 教案 搜索入门 hdu acm 教案 搜索入门
hdu2101AC代码
搜索 dfs 解题代码 hdu1241
hdu 5007 Post Robot 字符串枚举。 暴力一下就可以了。
hdu acm 教案 动态规划(1) hdu acm 教案 动态规划(1)
ACM HDU题目分类,我自己总结的大概只有十来个吧
hdu 1166线段树代码
HDU最全ac代码
自己做的HDU ACM已经AC的题目
hdu动态规划算法集锦
hdu题目分类
hdu2215 最简单的最小圆覆盖
HDU图论题目分类
hdu-acm源代码(上百题)hdu-acm源代码、hdu-acm源代码hdu-acm源代码