Geometry Darts
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 688 Accepted Submission(s): 178
Problem Description
Bob and Hannah like to play darts. They are not very good at it, however, so finishing a round of 501 Darts will take an eternity. They therefore decide to throw away the dartboard completely and put geometric shapes on the wall instead, awarding points according to the number of shapes the dart penetrates. To reduce the complexity of scoring, they only use circles, triangles and rectangles.
A game consists of each person throwing 3 darts each, and your job is to find the winner of the game, given the shapes and the throws.
A game consists of each person throwing 3 darts each, and your job is to find the winner of the game, given the shapes and the throws.
Input
The input will start with a line giving the total number of shapes, S. Then follow S lines describing the shapes, in either of the following formats:
1. C x y r, where (x, y) is the center of the circle, and r is the radius.
2. R x1 y1 x2 y2, where (x1, y1) and (x2, y2) are two corners of the rectangle with x1 < x2 and y1 < y2.
3. T x1 y1 x2 y2 x3 y3, where (xi, yi) are the three corners of the triangle.
Then follows a line with N, the number of games Bob and Hannah play. Each game is described with six lines giving the x and y coordinates of the 6 throws, the first three by Bob and the last three by Hannah.
1. C x y r, where (x, y) is the center of the circle, and r is the radius.
2. R x1 y1 x2 y2, where (x1, y1) and (x2, y2) are two corners of the rectangle with x1 < x2 and y1 < y2.
3. T x1 y1 x2 y2 x3 y3, where (xi, yi) are the three corners of the triangle.
Then follows a line with N, the number of games Bob and Hannah play. Each game is described with six lines giving the x and y coordinates of the 6 throws, the first three by Bob and the last three by Hannah.
Output
Output the name of the winner on a separate line for each game, or Tied if there is a tie.
Notes and Constraints
0 < S <= 1000
0 < N <= 1000
All rectangles have sides parallell to the x- and y-axis.
For triangle specifications, the three points will never be collinear.
All coordinates are given with double precision, with up to 6 decimals after the
decimal points.
All shapes are bounded by the rectangle defined by the two points (-1000,-1000)
and (1000, 1000).
All throws are guaranteed to be at least 10^-6 away from any shape boundary.
Notes and Constraints
0 < S <= 1000
0 < N <= 1000
All rectangles have sides parallell to the x- and y-axis.
For triangle specifications, the three points will never be collinear.
All coordinates are given with double precision, with up to 6 decimals after the
decimal points.
All shapes are bounded by the rectangle defined by the two points (-1000,-1000)
and (1000, 1000).
All throws are guaranteed to be at least 10^-6 away from any shape boundary.
Sample Input
3
C 0.0 0.0 5.0
R -1.0 -1.0 7.0 7.0
T 0.0 0.0 -3.0 0.0 0.0 -8.0
1
0.0 4.1
0.0 6.2
0.0 8.1
-0.5 -0.5
-0.5 -2.0
-0.5 -5.1
Sample Output
Hannah
计算几何,开始一直用面积法判断点是否在三角形内,不过一直WA,不知是有精度问题还是自己写挫了,后来改成同向法才A,改的乱七八糟,巨挫。
#include <iostream> #include <stdio.h> #include <math.h> #include <string.h> using namespace std; const double esp = 1e-10; #define N 1005 char str[10]; int i,j,k; struct Point{ double x,y; Point(double x = 0,double y = 0):x(x),y(y){} }; struct Circle{ Point A; double r; }c[N]; struct Triangles{ Point A,B,C; }t[N]; struct Rectangles{ Point A,B; }r[N]; typedef Point Vector; Vector operator - (Vector A ,Vector B) {return Vector(A.x-B.x,A.y-B.y);} double Dot(Vector A ,Vector B) {return A.x*B.x+A.y*B.y;} double Length(Vector A) {return sqrt(Dot(A,A));} double Cross(Vector A,Vector B) {return A.x*B.y-A.y*B.x;} int judge(Point A) { int p = 0,count = 0; for(p = 0 ; p < i ; p++) if(Length(A-c[p].A)<=c[p].r) count++; for(p = 0 ; p < k ; p++) if(A.x<=r[p].B.x&&A.y<=r[p].B.y&&A.x>=r[p].A.x&&A.y>=r[p].A.y) count++; for(p = 0 ; p < j ; p++) { if(Cross(t[p].C-t[p].B,t[p].A-t[p].B)*Cross(A-t[p].B,t[p].A-t[p].B)>0&& Cross(t[p].A-t[p].C,t[p].B-t[p].C)*Cross(A-t[p].C,t[p].B-t[p].C)>0&& Cross(t[p].B-t[p].A,t[p].C-t[p].A)*Cross(A-t[p].A,t[p].C-t[p].A)>0) count++; } return count; } int main() { int s,n,ans1 = 0,ans2 = 0;i = j = k =0; scanf("%d",&s); while(s--) { scanf("%s",str); if(str[0] == 'C'){ scanf("%lf %lf %lf",&c[i].A.x,&c[i].A.y,&c[i].r);i++; }else if(str[0] == 'T'){ scanf("%lf %lf %lf %lf %lf %lf",&t[j].A.x,&t[j].A.y,&t[j].B.x,&t[j].B.y,&t[j].C.x,&t[j].C.y);j++; }else { scanf("%lf %lf %lf %lf",&r[k].A.x,&r[k].A.y,&r[k].B.x,&r[k].B.y);k++; } } scanf("%d",&n); Point A; int p = 0; while(n--) { ans1 = ans2 = 0; for(p = 0 ; p < 3 ; p++) { scanf("%lf %lf",&A.x,&A.y); ans1+=judge(A); } for(p = 0 ; p < 3 ; p++) { scanf("%lf %lf",&A.x,&A.y); ans2+=judge(A); } if(ans1<ans2) printf("Hannah "); else if(ans1>ans2) printf("Bob "); else printf("Tied "); } return 0; }