就是一个点从开始的点在一个矩形内往某个方向一直运动,如果碰到了矩形的边,那么就反弹,我们可以把这个矩形拓展开,那么就是问题变成了我有没有一个点,这个点的坐标(Tx, Ty)满足n|Tx,m|Ty
那么假设有的话,那么这个直线的方程化简以后就是就是n*xx+m*yy = y-x,然后问题就变成了这个方程有没有解,如果我无解,那么就是-1,如果有解,那么就求出xx和yy的最小值,然后通过xx,yy的奇偶性来判断我进入边界的位置是哪里.
这是对于方向在右上角的,对于其他方向上我们可以转化到右上角,比如如果是左上角,那么就可以让现在的x = n - x, 最后的答案xx进行相应的变化 xx = n - xx,其他方向同理。
#include<map>
#include<set>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define first fi
#define second se
#define lowbit(x) (x & (-x)) typedef unsigned long long int ull;
typedef long long int ll;
const double pi = 4.0*atan(1.0);
const int inf = 0x3f3f3f3f;
const int maxn = ;
const int maxm = ;
using namespace std; int n, m, tol, T; ll e_gcd(ll a, ll b, ll &x, ll &y) {
if(b == ) {
x = ;
y = ;
return a;
} else {
ll d = e_gcd(b, a%b, x, y);
ll tmp = y;
y = x - a/b*y;
x = tmp;
return d;
}
} int main() {
int x,y,vx,vy;
scanf("%d%d%d%d%d%d", &n, &m, &x, &y, &vx, &vy);
if(vx == && vy == ) {
printf("-1\n");
return ;
}
if(vx == ) {
if(x == n || x == ) {
if(vy == )
printf("%d %d\n", x, m);
else
printf("%d %d\n", x, );
} else {
printf("-1\n");
}
return ;
}
if(vy == ) {
if(y == m || y == ) {
if(vx == )
printf("%d %d\n", n, y);
else
printf("%d %d\n", , y);
} else {
printf("-1\n");
}
return ;
}
bool fx = false;
bool fy = false;
if(vx == -) {
fx = true;
x = n - x;
}
if(vy == -) {
fy = true;
y = m - y;
}
ll a = n;
ll b = m;
ll c = x - y;
ll xx, yy;
ll d = e_gcd(a, b, xx, yy);
if(c % d) {
printf("-1\n");
return ;
}
ll r = b / d;
ll cx = ((c/d) * xx % r + r + r - ) %r + ;
ll cy = (cx * n - c) / m;
ll ansx, ansy;
if(cx & ) {
ansx = n;
} else {
ansx = ;
}
if(cy & ) {
ansy = m;
} else {
ansy = ;
}
if(fx) ansx = (ll)n - ansx;
if(fy) ansy = (ll)m - ansy;
printf("%lld %lld\n", ansx, ansy);
return ;
}