解题思路:
考虑当质点移动轨迹的直线斜率为1的时候,有轨迹方程 y = x + c,显然把原先起点x1,y1代入就可以求出c的值.
将质点的反弹等价于直线轨迹(由对称性质可得)。由x - y = -c得,要使得质点可以从顶角出去就等价于质点的直线轨迹会经过一点
(a*n,b*m),代入方程得a*n - b*m = -c,要使方程有解gcd(n,m) | c, c = k*gcd(n,m),根据扩展欧几里得就可以求出方程得一个解。初始化 x = k就可以得到c的一个解,等价于gcd(n,m)*k,因为k是可以提取的所以没有影响.另t*n%m==0,那么最小正整数t就是m/gcd(n,m),所以最小的a肯定是在t之内所以a要对t求余求最小的那个坐标.
至于其他方向向量不是(1,1)的可以用过对称转化为向量(1,1)去求解.
矩形平铺在坐标轴的坐标位置有明显的规律可循,画图就可以直接看出来了.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll x,y,c;
void ex_euclid(ll a,ll b)
{
if(!b){
x = c;
y = 0;
}else{
ex_euclid(b,a%b);
ll tem =x;
x = y;
y = tem - a/b*y;
}
}
int main()
{
int n,m,x1,y1,vx,vy;
scanf("%d%d%d%d%d%d",&n,&m,&x1,&y1,&vx,&vy);
if(!vx&&!vy) return 0*puts("-1");
if(vx&&!vy){
if(y1==0){
if(vx==-1) printf("0 0\n");
else printf("%d 0\n",n);
}else if(y1==m){
if(vx==-1) printf("0 %d\n",m);
else printf("%d %d\n",n,m);
}else puts("-1");
return 0;
}if(!vx&&vy){
if(x1==0){
if(vy==-1) printf("0 0\n");
else printf("0 %d\n",m);
}else if(x1==n){
if(vy==-1) printf("%d 0\n",n);
else printf("%d %d\n",n,m);
}else puts("-1");
return 0;
}
int fx = 0,fy = 0;
if(vx==-1) fx = 1,x1 = n - x1;
if(vy==-1) fy = 1,y1 = m - y1;
int g = __gcd(n,m),_m = m/g;
c = (x1-y1)/g;
if((x1-y1)%g!=0) return 0*puts("-1");
ex_euclid(n,m);
x = (x%_m + _m - 1)%_m + 1,y = -((x1-y1)-x*n)/m;//x为0时应该是_m
int ansn = n,ansm = m;
if(x%2==0) ansn = n - ansn;
if(y%2==0) ansm = m - ansm;
if(fx) ansn = n - ansn;//对称取反(坐标上的规律)
if(fy) ansm = m - ansm;
printf("%d %d\n",ansn,ansm);
return 0;
}