結果
| 問題 |
No.283 スライドパズルと魔方陣
|
| コンテスト | |
| ユーザー |
maspy
|
| 提出日時 | 2020-05-03 16:03:06 |
| 言語 | Python3 (3.13.1 + numpy 2.2.1 + scipy 1.14.1) |
| 結果 |
AC
|
| 実行時間 | 513 ms / 2,000 ms |
| コード長 | 3,154 bytes |
| コンパイル時間 | 200 ms |
| コンパイル使用メモリ | 13,312 KB |
| 実行使用メモリ | 45,052 KB |
| 最終ジャッジ日時 | 2024-06-12 20:06:28 |
| 合計ジャッジ時間 | 23,450 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 39 |
ソースコード
import sys
import numpy as np
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
def f(N):
if N % 4 == 0:
return f0(N)
elif N % 4 == 2:
return f2(N)
else:
return f13(N)
def f13(N):
A = np.zeros((N, N), np.int32)
x = 0
y = N // 2
for i in range(1, N * N + 1):
if A[x][y]:
x += 2
y -= 1
x %= N
y %= N
A[x, y] = i
x -= 1
y += 1
x %= N
y %= N
return A
def f0(N):
A = np.arange(N * N).reshape(N, N)
A[1::4, 0::4] *= -1
A[1::4, 3::4] *= -1
A[2::4, 0::4] *= -1
A[2::4, 3::4] *= -1
A[0::4, 1::4] *= -1
A[0::4, 2::4] *= -1
A[3::4, 1::4] *= -1
A[3::4, 2::4] *= -1
A[A < 0] += N * N - 1
A += 1
return A
def f2(N):
A = f(N // 2)
A = np.repeat(A, 2, axis=0).repeat(2, axis=1)
A = (A - 1) * 4
n = N // 4
# L-type
A[:2 * n + 2:2, ::2] += 4
A[:2 * n + 2:2, 1::2] += 1
A[1:2 * n + 2:2, ::2] += 2
A[1:2 * n + 2:2, 1::2] += 3
# U-type
A[2 * n + 2, ::2] += 1
A[2 * n + 2, 1::2] += 4
A[2 * n + 3, ::2] += 2
A[2 * n + 3, 1::2] += 3
# X-type
A[2 * n + 4::2, ::2] += 1
A[2 * n + 4::2, 1::2] += 4
A[2 * n + 5::2, ::2] += 3
A[2 * n + 5::2, 1::2] += 2
# modify center
A[2 * n, 2 * n] -= 3
A[2 * n, 2 * n + 1] += 3
A[2 * n + 2, 2 * n] += 3
A[2 * n + 2, 2 * n + 1] -= 3
return A
N = int(readline())
A = np.array(read().split()).reshape(N, N).astype(np.int32)
def check(A, B):
N = A.shape[0]
A = A.ravel()
B = B.ravel()
Ax, Ay = np.divmod(np.argmax(A), N)
Bx, By = np.divmod(np.argmax(B), N)
pos_A = np.empty_like(A)
pos_A[A] = np.arange(N * N)
B = pos_A[B]
inv = 0
for i, x in enumerate(B):
inv += np.sum(B[:i] > x)
dist = abs(Ax - Bx) + abs(Ay - By)
return (inv - dist) % 2 == 0
def solve(A):
N = A.shape[0]
if N == 1:
return A
if N == 2:
return None
if N == 3:
B = f(N) - 1
if check(A, B):
return B
else:
return B[::-1]
if N % 2 == 0:
B = f(N) - 1
if check(A, B):
return B
else:
return B[::-1]
if N % 3 != 0:
# 完全方陣
x = np.arange(N)
B0 = np.add.outer(x, 2 * x) % N
B1 = B0.T
B = N * B0 + B1
if check(A, B):
return B
return np.roll(B, 1, axis=0)
# N は 3 の倍数
M = N // 3
C = (f(M) - 1) * 9
D = f(3) - 1
B = np.empty_like(A)
for i in range(3):
for j in range(3):
B[i::3, j::3] = C + D[i, j]
if check(A, B):
return B
x, y = divmod(np.argmax(C), M)
temp = B[3 * x, 3 * y:3 * y + 3].copy()
B[3 * x, 3 * y:3 * y + 3] = B[3 * x + 2, 3 * y:3 * y + 3]
B[3 * x + 2, 3 * y:3 * y + 3] = temp
return B
A[A == 0] = N * N
A -= 1
B = solve(A)
if B is None:
print('impossible')
else:
print('possible')
B += 1
print('\n'.join(' '.join(row) for row in B.astype(str)))
maspy