Codeforces 92B (123B) Squares

問題

二次元平面上の格子点を考える。
格子の座標を(x, y)が悪い点であるとは、与えられた整数a, bに対して

x + y ≡ 0 (mod 2a)または
x - y ≡ 0 (mod 2b)のいずれかを満たすことを言う。


(x1, y1)から(x2, y2)へ、隣り合う格子点通って移動したい。
このとき、通らなければいけない悪い点の個数の最小値を求めよ。

制約条件

2≦a, b≦10^9
-10^9≦x1, y1, x2, y2≦10^9
(x1, y1), (x2, y2)はともに悪い点ではないことが保証されている。

方針

x + y ≡ 0 (mod 2a)の境界をまたがなければならない回数をc
x - y ≡ 0 (mod 2b)の境界をまたがなければならない回数をdとすると、
境界をまたぐときに、もう片方の境界も同時にまたげるので、max(c, d)が答え。


境界をまたぐ回数は、
(x1 + y1) / (2 * a) - (x2 + y2) / (2 * a)などとして求められるが、
負の数の場合の丸めが面倒なので、下のコードでは、2aの倍数だけずらして正にしている。

ソースコード

ll calc(int a, ll p, ll q){
	if(p > q) swap(p, q);
	if(p < 0){
		q += (abs(p) + a - 1) / a * a;
		p += (abs(p) + a - 1) / a * a;
	}
	return q / a - p / a;
}

int main(){
	int a, b, x, y, X, Y;
	cin >> a >> b >> x >> y >> X >> Y;
	
	ll c = calc(2 * a, x + y, X + Y), d = calc(2 * b, x - y, X - Y);
	cout << max(c, d) << endl;
	
	return 0;
}