2020 Multi-University Training Contest 3 1008 Triangle Collision
阿新 • • 發佈:2020-08-02
題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=6798
題意:一個邊長為L的等邊三角形,平面座標系的原點位於三角形底邊上的中點,三角形裡有一個小球的座標為(x,y),並在水平方向上有初始速度vx,在豎著方向上有初始速度vy,小球與三角形的邊相撞會反彈,並且速度不會變,讓你求小球與三角形相碰k次的時間。
思路:可以把三角形的三條邊當做鏡子,小球反彈可以看做在鏡子中遇到,鏡子中是有無數的等邊三角形的,然後二分時間,看小球穿過所以三角形的邊數。對於水平方向的底邊,只要看小球的豎著方向上的速度,很好算。對於其他兩條斜邊,只要將座標點繞等邊三角形的中心點分別旋轉 120,240 度就可以演算法碰撞次數。
#include<bits/stdc++.h> using namespace std; const double EPS=1e-6; const double PI=4.0*atan(1.0); const double base=2*PI/3; double L,vx,vy,x,y,h; int k; pair<double,double> get_point(const pair<double,double> &a,const double &rad) { return make_pair(a.first*cos(rad)-(a.second-h/3)*sin(rad),a.first*sin(rad)+(a.second-h/3)*cos(rad)+h/3); } bool ck(double times) { long long has=0; has+=abs(floor(get_point(make_pair(x+vx*times,y+vy*times),base*0).second/h)); has+=abs(floor(get_point(make_pair(x+vx*times,y+vy*times),base*1).second/h)); has+=abs(floor(get_point(make_pair(x+vx*times,y+vy*times),base*2).second/h)); return has>=k; } int main() { int T; cin>>T; while(T--) { cin>>L>>x>>y>>vx>>vy>>k; h=L*sqrt(3)/2; double l=0,r=1e11; while(r-l>EPS) { double mid=(l+r)/2; if(ck(mid)) r=mid; else l=mid; } printf("%.8lf\n",(l+r)/2); } }