先上题目:app
How Lader |
Lader is a game that is played in a regular hexagonal board (all sides equal, all angles are also equal). The game is much similar as pool game. But there is only one hole that is situated in the center of the hexagon. The position of the board is given by a 2D co-ordinate system. The top and bottom sides of the hexagon are parallel to x axis. The center of the hexagonal board is situated at (0,0).ide
You are trying to hit the ball B1 and the direction of hitting is from B1 to B2. After you have hit the ball B1, it starts reflecting on the walls of the hexagonal Lader board. The initial speed of the ball is given. When a ball hits a wall, its speed decreases by 1 unit/second. The ball stops when its' speed becomes 0unit/second.this
You have to determine the final speed of the ball when it falls through the hole. If the ball stops before reaching the hole, print `Stops'. In this problem assume the followings:spa
The picture on the right above shows the movements of a ball on a Lader board. The numbers written denote the order of appearance.code
The first line of the input denotes T ( 1T
150), the number of test cases to follow. Each test case consists of a 6 integers, s ( 0 < s < 150), x1, y1, x2, y2, r, t (1
t
500). Here, s denotes the length of sides of the hexagon centered at (0,0).orm
(x1, y1) and (x2, y2) denote the position of ball B1 and ball B2 respectively. The balls will be strictly inside the hexagonal board. r denotes the radius of the hole, centered at (0,0). The hole resides strictly inside the hexagonal board. t denotes the initial speed of the ball.blog
For each input, you have to print the case number first, followed by the terminal speed when it falls in the hole. If the ball stops before falling in the hole, print `Stops'.ci
4 80 10 0 20 0 5 200 51 7 4 0 9 5 1 55 -5 8 -6 7 8 104 12 1 0 0 -1 1 271
Case 1: 198 Case 2: Stops Case 3: 99
Problemsetter: Anna Fariha
Special Thanks: Md. Mahbubul Hasanterminal
题意:给你一个正六边形,中间有一个半径为R的洞,如今有一个球b1给他一个方向向量以及速度。球每一次碰撞六边形的边速度会减1,若是撞到角的话速度会减2,问你当球掉进洞里的时候速度是多少,若是尚未掉进洞里速度就小于等于0的话就输出"Stops"。get
几何+模拟。
判断射线是否穿过点,射线与线段相交,射线与圆的交点,以及向量的反射。这要这些都解决的话就没有太多问题了。
关于射线穿过点,射线与线段相交等,能够看一下该博客的一份几何模板。这里讲一下射线与圆的相交判断,射线与圆相交或者相切,能够用过解二元一次方程获得,根据判别式的值咱们能够判断蛇蝎和圆的相交状况。这与向量的反射这里给出一条公式:v'=v+N*2*fabs(Dot(v,N)),其中这里v是入射向量v'是出射向量,N是反射面的法线向量,Dot(v,N)是点积。这里须要注意的是求点积之后须要求绝对值,由于这里求点积的做用是为了求向量在法线上的投影长度,因此须要转成正数。
须要注意的地方是对于起点来讲,若是一开始它就在原的里面或者边上的话,那它就一开始就能够输出结果了(特别注意的是在边上的状况)。
上代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 #define MAX 10 6 using namespace std; 7 8 const double PI=2*acos(0); 9 const double der60=PI/3; 10 const double eps=1e-6; 11 const double sqrt3=sqrt(3); 12 13 int dcmp(double x){ 14 if(fabs(x)<eps) return 0; 15 return x>0 ? 1 : -1; 16 } 17 18 typedef struct Point{ 19 double x,y; 20 Point(double x=0,double y=0):x(x),y(y){} 21 }Point; 22 typedef Point Vector; 23 Vector operator + (Point A,Point B){ return Vector(A.x+B.x,A.y+B.y);} 24 Vector operator - (Point A,Point B){ return Vector(A.x-B.x,A.y-B.y);} 25 Vector operator * (Point A,double e){ return Vector(A.x*e,A.y*e);} 26 Vector operator / (Point A,double e){ return Vector(A.x/e,A.y/e);} 27 bool operator == (Point A,Point B){ return dcmp(A.x-B.x)==0 && dcmp(A.y-B.y)==0;} 28 double Dot(Vector A,Vector B){ return A.x*B.x+A.y*B.y;} 29 double Cross(Vector A,Vector B){ return A.x*B.y-A.y*B.x;} 30 double Length(Vector A){ return sqrt(Dot(A,A));} 31 32 Vector Rotate(Vector A,double rad){ 33 return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad)); 34 } 35 Vector Normal(Vector A){ 36 double L=Length(A); 37 if(dcmp(L)==0) return Vector(0,0); 38 return Vector(-A.y/L,A.x/L); 39 } 40 Point p[6],b1,b2,st; 41 Vector di; 42 double s; 43 int ti; 44 45 typedef struct Circle{ 46 Point c; 47 double r; 48 }Circle; 49 Circle cen; 50 51 int getLCI(Point p0,Vector v,double &t1,double &t2){ 52 double a=v.x; double b=p0.x-cen.c.x; 53 double c=v.y; double d=p0.y-cen.c.y; 54 double e=a*a+c*c; double f=2*(a*b+c*d); double g=b*b+d*d-cen.r*cen.r; 55 double delta=f*f-4*e*g; 56 if(dcmp(delta)<0) return 0; 57 if(dcmp(delta)==0){ 58 t1=t2=-f/(2*e); 59 return 1; 60 } 61 t1=(-f-sqrt(delta))/(2*e); 62 t2=(-f+sqrt(delta))/(2*e); 63 return 2; 64 } 65 bool OnSegment(Point p0,Point a1,Point a2){ 66 return (dcmp(Cross(a1-p0,a2-p0))==0 && dcmp(Dot(a1-p0,a2-p0))<0); 67 } 68 69 bool isPar(Point a1,Point a2){ 70 Vector v=a2-a1; 71 v=v/Length(v); 72 if(v==di || (v*-1)==di) return 1; 73 return 0; 74 } 75 76 77 Point GLI(Point P,Vector v,Point Q,Vector w){ 78 Vector u=P-Q; 79 double t=Cross(w,u)/Cross(v,w); 80 return P+v*t; 81 } 82 83 bool isOnLine(Point e){ 84 Vector u=e-st; 85 u=u/Length(u); 86 if(u==di) return 1; 87 return 0; 88 } 89 90 int solve(){ 91 int ans=ti; 92 double t1,t2; 93 Point tt; 94 Vector sv,ndi,normal; 95 bool f; 96 while(ans>0){ 97 if(getLCI(st,di,t1,t2)>0){ 98 if(t1>=0 || t2>=0) return ans; 99 } 100 f=0; 101 for(int i=0;i<6;i++){ 102 if(isOnLine(p[i])){ 103 st=p[i]; di=di*-1; 104 ans-=2; f=1; 105 break; 106 } 107 } 108 if(f) continue; 109 for(int i=0;i<6;i++){ 110 if(OnSegment(st,p[i],p[(i+1)%6])) continue; 111 if(isPar(p[i],p[(i+1)%6])) continue; 112 sv=p[(i+1)%6]-p[i]; 113 tt=GLI(st,di,p[i],sv); 114 if(isOnLine(tt) && OnSegment(tt,p[i],p[(i+1)%6])){ 115 st=tt; 116 normal=Normal(sv); 117 ndi=di+normal*2*fabs(Dot(di,normal)); 118 di=ndi; 119 di=di/Length(di); 120 ans--; 121 break; 122 } 123 } 124 } 125 return 0; 126 } 127 128 129 int main() 130 { 131 int t,ans; 132 Vector e; 133 //freopen("data.txt","r",stdin); 134 scanf("%d",&t); 135 for(int z=1;z<=t;z++){ 136 scanf("%lf %lf %lf %lf %lf %lf %d",&s,&b1.x,&b1.y,&b2.x,&b2.y,&cen.r,&ti); 137 di=b2-b1; 138 di=di/Length(di); 139 st=b1; 140 cen.c.x=cen.c.y=0; 141 p[0].x=-s; p[0].y=0; 142 p[1].x=-s/2; p[1].y=-s*sqrt3/2; 143 p[2].x=s/2; p[2].y=-s*sqrt3/2; 144 p[3].x=s; p[3].y=0; 145 p[4].x=s/2; p[4].y=s*sqrt3/2; 146 p[5].x=-s/2; p[5].y=s*sqrt3/2; 147 // for(int i=1;i<6;i++){ 148 // p[i]=Rotate(p[i-1],der60); 149 // } 150 ans=solve(); 151 printf("Case %d: ",z); 152 if(ans) printf("%d\n",ans); 153 else printf("Stops\n"); 154 } 155 return 0; 156 }