D - Shift Puzzle Editorial by toam
\(S\) と \(T\) に含まれる #
の個数が等しくない場合明らかに不可能です.逆に #
の個数が等しい場合は必ず \(N^3\) 手以内で一致させることが可能です.
以下,#
の個数が等しい場合の操作手順について述べます.
\((S_{x,y},T_{x,y})=\) \((\) #
\(,\) .
\()\) となる \((x,y)\) の個数と, \((S_{x,y},T_{x,y})=\) \((\) .
\(,\) #
\()\) となる \((x,y)\) の個数は等しいです.ここで, \((S_{x_1,y_1},T_{x_1,y_1})=\) \((\) #
\(, \) .
\()\), \((S_{x_2,y_2},T_{x_2,y_2})=\) \((\) .
\(,\) #
\()\) を満たす \((x_1,y_1),(x_2,y_2)\) を任意に選んだとき, \(2N\) 手の操作によって \((x_1,y_1),(x_2,y_2)\) の \(2\) 点 swap ( \(S_{x_1,y_1}\) = .
\(,S_{x_2,y_2}\) = #
にする)を行うことができます. \((S_{x,y},T_{x,y})=\) \((\) #
\(,\) .
\()\) となる \((x,y)\) の個数は高々 \(N^2/2\) 個ですから,全体で \(2N\times N^2/2=N^3\) 手以内で \(S\) を \(T\) に一致させることができます.
2 点 swap の方法
下図左上にあるような配置にある \(3\) つのマス \(X,Y,Z\)( \(X,Y\) は同じ行に, \(Y,Z\) は同じ列にある)に対して, \(2N\) 手の操作によって \((X,Y,Z)\) を \((Y,Z,X)\) や \((Z,X,Y)\) に同時に rotate することができます.(図では \((X,Y,Z)\) を \((Z,X,Y)\) に置き換える場合を示しています.)
ここで色の種類が \(2\) 種類しかないことを踏まえると, \(3\) つのマスの rotate を利用することで色の \(2\) 点 swap を実現することが可能です.
\(X,Z\) の色を swap する場合
\(Y\) のマスの色が \(X\) のマスの色と等しいか \(Z\) のマスの色と等しいかで場合分けします.
\(X,Y\) の色を swap する場合
\(Z\) のマスの色が \(X\) のマスの色と等しいか \(Y\) のマスの色と等しいかで場合分けします.
実装例 (Python)
def op(t, x, c):
for _ in range(c):
print(t + 1, x + 1)
def swap(x0, y0, x1, y1, f):
# X: (x0, y0), Y: (x0, y1), Z: (x1, y1)
if f:
# X -> Z, Z -> Y, Y -> X
op(0, x0, (y1 - y0) % n)
op(1, y1, (x0 - x1) % n)
op(0, x0, (y0 - y1) % n)
op(1, y1, (x1 - x0) % n)
else:
# X -> Y, Y -> Z, Z -> X
op(1, y1, (x0 - x1) % n)
op(0, x0, (y1 - y0) % n)
op(1, y1, (x1 - x0) % n)
op(0, x0, (y0 - y1) % n)
n = int(input())
S = [list(input()) for i in range(n)]
T = [list(input()) for i in range(n)]
S0, T0 = [], []
for x in range(n):
for y in range(n):
if S[x][y] == T[x][y]:
continue
if S[x][y] == ".":
S0.append((x, y))
if T[x][y] == ".":
T0.append((x, y))
if len(S0) != len(T0):
print("No")
exit()
print("Yes")
print(len(S0) * 2 * n)
for i in range(len(S0)):
x0, y0 = S0[i]
x1, y1 = T0[i]
if x0 != x1 and y0 != y1:
swap(x0, y0, x1, y1, S[x0][y1] == ".")
elif x0 == x1:
x2 = (x0 + 1) % n
swap(x0, y0, x2, y1, S[x0][y1] == S[x2][y1])
else:
y2 = (y1 + 1) % n
swap(x0, y2, x1, y1, S[x0][y2] == S[x1][y1])
S[x0][y0], S[x1][y1] = S[x1][y1], S[x0][y0]
posted:
last update: