結果
| 問題 | No.283 スライドパズルと魔方陣 |
| コンテスト | |
| ユーザー |
qwewe
|
| 提出日時 | 2025-05-14 13:22:34 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 6,491 bytes |
| 記録 | |
| コンパイル時間 | 210 ms |
| コンパイル使用メモリ | 82,560 KB |
| 実行使用メモリ | 77,184 KB |
| 最終ジャッジ日時 | 2025-05-14 13:24:55 |
| 合計ジャッジ時間 | 7,041 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 22 WA * 17 |
ソースコード
import sys
def solve():
N = int(sys.stdin.readline())
grid_input = []
for _ in range(N):
grid_input.append(list(map(int, sys.stdin.readline().split())))
if N == 2:
print("impossible")
return
# Memoization for inversion counting can speed it up if called with same tile list
memo_inversions = {}
def count_inversions(arr_tuple):
if arr_tuple in memo_inversions:
return memo_inversions[arr_tuple]
arr = list(arr_tuple)
n_len = len(arr)
inv_count = 0
for i in range(n_len):
for j in range(i + 1, n_len):
if arr[i] > arr[j]:
inv_count += 1
memo_inversions[arr_tuple] = inv_count
return inv_count
def get_solvability_invariant(current_grid, n_val, is_initial_puzzle_state):
tiles = []
entity_r, entity_c = -1, -1
n_sq_val = n_val * n_val
for r_idx in range(n_val):
for c_idx in range(n_val):
val = current_grid[r_idx][c_idx]
if is_initial_puzzle_state: # 0 is the blank
if val == 0:
entity_r, entity_c = r_idx, c_idx
else:
tiles.append(val)
else: # Target magic square, N^2 is the "blank"
if val == n_sq_val:
entity_r, entity_c = r_idx, c_idx
else:
tiles.append(val)
inversions = count_inversions(tuple(tiles))
entity_row_from_bottom = n_val - 1 - entity_r # 0-indexed from top, convert to 0-indexed from bottom
if n_val % 2 == 1: # N is odd
return inversions % 2
else: # N is even
return (inversions + entity_row_from_bottom) % 2
invariant_initial = get_solvability_invariant(grid_input, N, True)
def generate_magic_square(n_gen):
if n_gen == 0: return []
if n_gen == 1: return [[1]]
mg_square = [[0 for _ in range(n_gen)] for _ in range(n_gen)]
if n_gen % 2 == 1: # Odd N
r, c = 0, n_gen // 2
num = 1
while num <= n_gen * n_gen:
mg_square[r][c] = num
num += 1
r_prev, c_prev = r, c
r = (r - 1 + n_gen) % n_gen
c = (c + 1 + n_gen) % n_gen
if mg_square[r][c] != 0:
r = (r_prev + 1) % n_gen
c = c_prev
elif n_gen % 4 == 0: # Doubly Even N
for r_idx in range(n_gen):
for c_idx in range(n_gen):
mg_square[r_idx][c_idx] = (r_idx * n_gen) + c_idx + 1
for r_idx in range(n_gen):
for c_idx in range(n_gen):
if (r_idx % 4 == c_idx % 4) or ((r_idx % 4) + (c_idx % 4) == 3):
mg_square[r_idx][c_idx] = (n_gen * n_gen + 1) - mg_square[r_idx][c_idx]
else: # Singly Even N (N % 4 == 2) - Strachey's method
m = n_gen // 2
def make_odd_sub_square(size, start_val_offset):
sub_sq = [[0 for _ in range(size)] for _ in range(size)]
r_s, c_s = 0, size // 2
curr_num_in_sub = 1
while curr_num_in_sub <= size * size:
sub_sq[r_s][c_s] = curr_num_in_sub + start_val_offset
curr_num_in_sub += 1
r_s_prev, c_s_prev = r_s, c_s
r_s = (r_s - 1 + size) % size
c_s = (c_s + 1 + size) % size
if sub_sq[r_s][c_s] != 0:
r_s = (r_s_prev + 1) % size
c_s = c_s_prev
return sub_sq
s1_vals = make_odd_sub_square(m, 0)
s2_vals = make_odd_sub_square(m, m*m)
s3_vals = make_odd_sub_square(m, 2*m*m)
s4_vals = make_odd_sub_square(m, 3*m*m)
for r_idx in range(m):
for c_idx in range(m):
mg_square[r_idx][c_idx] = s1_vals[r_idx][c_idx]
mg_square[r_idx][c_idx+m] = s3_vals[r_idx][c_idx]
mg_square[r_idx+m][c_idx] = s4_vals[r_idx][c_idx]
mg_square[r_idx+m][c_idx+m] = s2_vals[r_idx][c_idx]
k_strachey = (m - 1) // 2
for r_s_idx in range(m):
for c_s_idx in range(k_strachey):
mg_square[r_s_idx][c_s_idx], mg_square[r_s_idx+m][c_s_idx] = \
mg_square[r_s_idx+m][c_s_idx], mg_square[r_s_idx][c_s_idx]
middle_col_sub_idx = m // 2
for r_s_idx in range(m):
if r_s_idx != (m // 2):
mg_square[r_s_idx][middle_col_sub_idx], mg_square[r_s_idx+m][middle_col_sub_idx] = \
mg_square[r_s_idx+m][middle_col_sub_idx], mg_square[r_s_idx][middle_col_sub_idx]
for r_s_idx in range(m):
for c_offset in range(k_strachey):
c_s_idx_in_subgrid = (m - 1) - c_offset
global_c_idx_for_s3s2_part = c_s_idx_in_subgrid + m
mg_square[r_s_idx][global_c_idx_for_s3s2_part], mg_square[r_s_idx+m][global_c_idx_for_s3s2_part] = \
mg_square[r_s_idx+m][global_c_idx_for_s3s2_part], mg_square[r_s_idx][global_c_idx_for_s3s2_part]
return mg_square
candidate_magic_squares = []
m_canonical = generate_magic_square(N)
candidate_magic_squares.append(m_canonical)
if N > 0: # Check N>0 to avoid issues with N=0 if it were possible
m_reflected = [[0 for _ in range(N)] for _ in range(N)]
is_different = False
for r_idx in range(N):
for c_idx in range(N):
m_reflected[r_idx][c_idx] = m_canonical[r_idx][N - 1 - c_idx]
if m_reflected[r_idx][c_idx] != m_canonical[r_idx][c_idx]:
is_different = True
if is_different:
candidate_magic_squares.append(m_reflected)
for ms_candidate in candidate_magic_squares:
invariant_magic_square = get_solvability_invariant(ms_candidate, N, False)
if invariant_initial == invariant_magic_square:
print("possible")
for r_idx in range(N):
print(*(ms_candidate[r_idx]))
return
print("impossible")
solve()
qwewe