3 10 10 1 1 9 9 10 10 0 5 5 10 10 10 1 0 1 10
Case #1: 6.0 6.0 Case #2: Collision will not happen. Case #3: 6.0 5.0HintIn first example, two balls move from (1, 1) and (9, 9) both with velocity (1, 1), the ball starts from (9, 9) will rebound at point (10, 10) then move with velocity (−1, −1). The two balls will meet each other at (6, 6).
最后求一个k1>0的最小正整数解。用一下扩展欧几里得即可。
时间t=k1*x-(x0+x1)/2,有了t就可以算最后的坐标x了,注意模上2x,然后如果大于x,还要用2x减去这个数。同理可以算得y。
代码:
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #define ll long long #define eps 1e-6 using namespace std; ll myabs(ll x){ return x>=0?x:-x; } double fabs(double x){ return x>0?x:-x; } void extend_gcd(ll a,ll b,ll &x,ll &y,ll &q){ if(b==0){x=1;y=0;q=a;} else{ extend_gcd(b,a%b,x,y,q); ll tmp=x;x=y;y=tmp-a/b*y; } } int main() { int t,cas=1; ll x,y,x0,y0,x1,y1; double tt,ansx,ansy; cin>>t; while(t--){ cin>>x>>y>>x0>>y0>>x1>>y1; printf("Case #%d:\n",cas++); if(x0==x1&&y0==y1) printf("%.1f %.1f\n",1.0*x0,1.0*y0); else if(x0==x1){ tt=y-1.0*(y0+y1)/2; ansy=y0+tt>y?2*y-y0-tt:y0+tt; ansx=x0+tt>x?2*x-x0-tt:x0+tt; printf("%.1f %.1f\n",ansx,ansy); } else if(y0==y1){ tt=x-1.0*(x0+x1)/2; ansy=x0+tt>x?2*x-x0-tt:x0+tt; ansx=y0+tt>y?2*y-y0-tt:y0+tt; printf("%.1f %.1f\n",ansx,ansy); } else{ if((x0+x1-y0-y1)%2) {puts("Collision will not happen.");continue;} ll k=(x0+x1-y0-y1)/2; ll a,b,xt,yt,q; a=x,b=-y; extend_gcd(a,b,xt,yt,q); if(k%q) {puts("Collision will not happen.");continue;} else{ xt*=k/q; ll z=xt/(y/q); xt-=y/q*z; if(xt<1) xt+=myabs(y/q); tt=xt*x-(x0+x1)*1.0/2; ll d=floor((x0+tt)/(2*x)+eps); double tx,ty; tx=x0+tt-2*x*d; d=floor((y0+tt)/(2*y)+eps); ty=y0+tt-2*y*d; ansx=tx>x?2*x-tx:tx; ansy=ty>y?2*y-ty:ty; printf("%.1f %.1f\n",ansx,ansy); } } } return 0; }