UVa - 12617 - How Lader

先上題目: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

 


$\textstyle \parbox{.5\textwidth}{
\begin{center}
\mbox{}
\epsfbox{p12617a.eps}
\end{center}}$$\textstyle \parbox{.49\textwidth}{
\begin{center}
\mbox{}
\epsfbox{p12617b.eps}
\end{center}}$

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 $ \le$ 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

 

  1. There is no loss of speed while rolling freely on the board.
  2. The radius of the ball is so small that you can consider it as a point.
  3. You may consider the ball fallen in the hole, if at any point the ball is situated at a distance closer than r + 10-6 units from the center of the hole, where r is the radius of the hole.
  4. The reflection happens according to the standard reflection rule (incident angle = reflection angle, with respect to the side of the hexagon) except for the case when it hits the corner. That case is described in 5-th rule.
  5. If a ball reaches at the corner (intersection point of two sides), its speed decreases by 2 (it is assumed that it hits both the walls) and it comes back along the line it hits that corner. If a ball with speed 1 hits the corner, it stops there.

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

 

Input 

The first line of the input denotes T ( 1$ \le$T$ \le$150), the number of test cases to follow. Each test case consists of a 6 integers, s ( 0 < s < 150), x1, y1, x2, y2, rt (1$ \le$t$ \le$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

 

Output 

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

 

Sample Input 

 

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

 

Sample Output 

 

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 }
/*12617*/
相關文章
相關標籤/搜索