問題設定を整理
点 を中心として、点と対称な位置をとします。
すると、
より、
となります。この式から、 が偶数のとき は偶数、 が奇数のとき は奇数ということがわかります。 についても同じです。
そのため、スタート地点とゴール地点の座標の偶奇が違う場合はゴールに移動できないことがわかります。
移動を 2回行う場合を考えます。1回目が 点 を中心、2回目が 点 を中心とした移動の場合、点 は
点 に移動します。
つまり、 の変化量の移動になります。
2回移動を1セットとして、スタート地点からゴール地点に近づけていくことができます。
以下、 座標について考えます。
の場合、 しか選べないため、スタート地点の と にしか移動できません。
の場合、偶数回の移動であればよく、 の場合、奇数回の移動であればよいです。
奇数回の移動については、スタート地点から 1回移動した状態をあらためてスタート地点と考えれば、あとは偶数回の移動であればよくなります。
の場合、 とすれば 2回の移動で座標は と変化し、
とすれば と変化します。
問題の制約から、 と の差は最大でも であるため、2回の移動で 2ずつ近づいていく場合でも
回の移動になり、 回以下という条件は満たします。そのため、移動回数の上限の制約でゴールに届かないということはありません。
コード例 (Julia)
function solve() # 入力 readInts() = parse.(Int,split(readline())) readInt() = parse(Int,readline()) # 入力データ sx, sy = readInts() tx, ty = readInts() a,b,c,d = readInts() dx = tx - sx dy = ty - sy if dx % 2 != 0 || dy % 2 != 0 # 移動しても 奇数座標は奇数座標、偶数座標は偶数座標 のままなので、 # 偶奇が異なる先には移動できない println("No") return end move1step = false # 偶数回移動だけゴールに到達できない場合、1回移動する if (a == b && sx != tx) || (c == d && sy != ty) sx = 2a - sx sy = 2c - sy move1step = true # 残り偶数回移動だけゴールに到達できない場合 if (a == b && sx != tx) || (c == d && sy != ty) println("No") return end end # ここまで問題なければ、ゴールに到達可能 println("Yes") # 1回移動していた場合、"Yes" 出力後に移動を出力 if move1step println(a," ",c) end # あとは2回の移動を1セットとしてゴールに近づいていく while sx != tx || sy != ty if sx < tx x1 = a x2 = min(b, a + div(tx - sx,2)) else x1 = b x2 = max(a, b - div(sx - tx,2)) end if sy < ty y1 = c y2 = min(d, c + div(ty - sy,2)) else y1 = d y2 = max(c, d - div(sy - ty,2)) end println(x1," ",y1) println(x2," ",y2) sx += 2*(x2-x1) sy += 2*(y2-y1) end end # function solve # main solve()