CF#484 Div.2 E. Billiard
? 解题记录 ? ? Codeforces ? ? 扩展欧几里得 ?    2018-07-05 23:00:10    680    0    0
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Consider a billiard table of rectangular size n×mn×m with four pockets. Let's introduce a coordinate system with the origin at the lower left corner (see the picture).

There is one ball at the point (x,y)(x,y) currently. Max comes to the table and strikes the ball. The ball starts moving along a line that is parallel to one of the axes or that makes a 4545∘ angle with them. We will assume that:

  1. the angles between the directions of the ball before and after a collision with a side are equal,
  2. the ball moves indefinitely long, it only stops when it falls into a pocket,
  3. the ball can be considered as a point, it falls into a pocket if and only if its coordinates coincide with one of the pockets,
  4. initially the ball is not in a pocket.

Note that the ball can move along some side, in this case the ball will just fall into the pocket at the end of the side.

Your task is to determine whether the ball will fall into a pocket eventually, and if yes, which of the four pockets it will be.

Input

The only line contains 66 integers nnmmxxyyvxvxvyvy (1n,m1091≤n,m≤1090xn0≤x≤n0ym0≤y≤m1vx,vy1−1≤vx,vy≤1(vx,vy)(0,0)(vx,vy)≠(0,0)) — the width of the table, the length of the table, the xx-coordinate of the initial position of the ball, the yy-coordinate of the initial position of the ball, the xx-component of its initial speed and the yy-component of its initial speed, respectively. It is guaranteed that the ball is not initially in a pocket.

Output

Print the coordinates of the pocket the ball will fall into, or 1−1 if the ball will move indefinitely.

Examples
input
Copy
4 3 2 2 -1 1
output
Copy
0 0
input
Copy
4 4 2 0 1 1
output
Copy
-1
input
Copy
10 10 10 1 -1 0
output
Copy
-1
Note

The first sample:

The second sample:

In the third sample the ball will never change its yy coordinate, so the ball will never fall into a pocket.

大概是说给你一张n*m的台球桌,四个角有洞,你从(x,y)打一个台球,初速度只能是水平、竖直或者倾角为45°(两种方向)。问你最后这个台球会不会掉进洞里,如果会,掉进哪个洞。

然后发现这是一道物理题……首先水平竖直我们可以特判,然后我们考虑斜着。我们先转台球桌,让台球打出的方向在第一象限,然后我们把台球桌沿着第一象限翻着铺开,这样台球的路径变成了一条直线,然后问题就变成了一根直线y=x+c上满足x是n的倍数,y是m的倍数的点。我们化一下,就是Y*m = n * X+c的最小正整数解,就是扩展欧几里得的裸题了。

代码有点骚……把自己转晕了……

#include<cstdio>
#include<algorithm>
#include<iostream>
#define LL long long
using namespace std;
LL n, m, x, y, vx, vy, cox[6][3];
LL ext_gcd(LL a, LL b, LL & x, LL & y) {
	if(b == 0) {x = 1, y = 0; return a;}
	LL d = ext_gcd(b, a % b, x, y);
	LL x1 = y, y1 = x - (a / b) * y;
	return x = x1, y = y1, d;
}

void solve() {
	LL ansx = 0, ansy = 0, c = y - x;
	LL d = ext_gcd(m, -n, ansy, ansx);
	if(c % d != 0) return cout << "-1", void();
	ansx *= (c / d), ansy *= (c / d);
	LL newx = ansx, newy = ansy;
	if(d > 0) d = -d;
	if(ansx <= 0){
		newy = ansy - (n / d) * ((0 - ansx) / (-m / d) + 1);
		newx = ansx + (-m / d) * ((0 - ansx) / (-m / d) + 1);
	}
	ansx = newx, ansy = newy;
	if(ansy <= 0){
		newy = ansy - (n / d) * ((0 - ansy) / (n / d) + 1);
		newx = ansx + (-m / d) * ((0 - ansy) / (n / d) + 1);
	}
	LL tmp = min((ansx - 1) / (-m / d), (ansy - 1) / (-n / d));
	newy = ansy + (n / d) * (tmp);
	newx = ansx - (-m / d) * (tmp);
	if((newx % 2) && (newy % 2)) cout << cox[2][0] << " " << cox[2][1];
	if((newx % 2) && !(newy % 2)) cout << cox[3][0] << " " << cox[3][1];
	if(!(newx % 2) && (newy % 2)) cout << cox[1][0] << " " << cox[1][1];
	if(!(newx % 2) && !(newy % 2)) cout << cox[0][0] << " " << cox[0][1];
}

void turn() {
	LL nx = y, ny = n - x;
	y = ny, x = nx, swap(n, m);
	LL tmp[4] = {cox[3][0], cox[3][1]};
	for(register int i = 3; i > 0; --i)
		cox[i][0] = cox[i - 1][0], cox[i][1] = cox[i - 1][1];
	cox[0][0] = tmp[0], cox[0][1] = tmp[1];
}

int main() {
	cin >> n >> m >> x >> y >> vx >> vy;
	cox[0][0] = 0, cox[0][1] = 0;
	cox[1][0] = 0, cox[1][1] = m;
	cox[2][0] = n, cox[2][1] = m;
	cox[3][0] = n, cox[3][1] = 0;
	for(register int i = 0; i < 4; ++i)
		if(x == cox[i][0] && y == cox[i][1])
			cout << cox[i][0] << " " << cox[i][1];
	if(!vx) if(x != 0 && x != n) return (cout << "-1"), 0;
	else {
		if(y != 0 && y != m)
			if(vy < 0) y = 0;else y = m;
		cout << x << " " << y;return 0;
	}
	if(!vy) if(y != 0 && y != m) return (cout << "-1"), 0;
	else {
		if(x != 0 && x != n)
			if(vx < 0) x = 0;else x = n;
		cout << x << " " << y;return 0;
	}
	if(vx < 0 && vy > 0) turn();
	if(vx < 0 && vy < 0) turn(), turn();
	if(vx > 0 && vy < 0) turn(), turn(), turn();
	solve();
	return 0;
}


上一篇: 洛谷P3644 [APIO2015]八邻旁之桥

下一篇: UOJ#79. 一般图最大匹配

680 人读过
立即登录, 发表评论.
没有帐号? 立即注册
0 条评论
文档导航