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; }