from collections import deque
def string_to_coords(pos):
col_char = pos[0]
row_char = pos[1:]
x = ord(col_char) - ord('a')
y = int(row_char) - 1
return x, y
def coords_to_string(x, y):
col_char = chr(x + ord('a'))
row_char = str(y + 1)
return col_char + row_char
def get_knight_moves(x, y, N):
moves = [
(x + 1, y + 2), (x + 1, y - 2),
(x - 1, y + 2), (x - 1, y - 2),
(x + 2, y + 1), (x + 2, y - 1),
(x - 2, y + 1), (x - 2, y - 1)
]
valid_moves = []
for nx, ny in moves:
if 0 <= nx < N and 0 <= ny < N:
valid_moves.append((nx, ny))
return valid_moves
def print_all_shortest_paths(N, start_pos, end_pos):
start_x, start_y = string_to_coords(start_pos)
target_x, target_y = string_to_coords(end_pos)
distances = [[-1] * N for _ in range(N)]
distances[start_x][start_y] = 0
queue = deque([(start_x, start_y)])
while queue:
cx, cy = queue.popleft()
if cx == target_x and cy == target_y:
break
current_dist = distances[cx][cy]
for nx, ny in get_knight_moves(cx, cy, N):
if distances[nx][ny] == -1:
distances[nx][ny] = current_dist + 1
queue.append((nx, ny))
if distances[target_x][target_y] == -1:
print("Шляху не існує")
return
all_paths = []
def find_paths_dfs(current_x, current_y, current_path):
if current_x == target_x and current_y == target_y:
all_paths.append(list(current_path))
return
current_dist = distances[current_x][current_y]
for nx, ny in get_knight_moves(current_x, current_y, N):
if distances[nx][ny] == current_dist + 1:
current_path.append(coords_to_string(nx, ny))
find_paths_dfs(nx, ny, current_path)
current_path.pop()
initial_path = [start_pos]
find_paths_dfs(start_x, start_y, initial_path)
print(f"Мінімальна кількість ходів: {distances[target_x][target_y]}")
print(f"Знайдено варіантів шляху: {len(all_paths)}")
for path in all_paths:
print(" -> ".join(path))
N = 10000
start = "a1"
end = "d4"
print_all_shortest_paths(N, start, end)
ZnJvbSBjb2xsZWN0aW9ucyBpbXBvcnQgZGVxdWUKCmRlZiBzdHJpbmdfdG9fY29vcmRzKHBvcyk6CiAgICBjb2xfY2hhciA9IHBvc1swXQogICAgcm93X2NoYXIgPSBwb3NbMTpdCiAgICB4ID0gb3JkKGNvbF9jaGFyKSAtIG9yZCgnYScpCiAgICB5ID0gaW50KHJvd19jaGFyKSAtIDEKICAgIHJldHVybiB4LCB5CgpkZWYgY29vcmRzX3RvX3N0cmluZyh4LCB5KToKICAgIGNvbF9jaGFyID0gY2hyKHggKyBvcmQoJ2EnKSkKICAgIHJvd19jaGFyID0gc3RyKHkgKyAxKQogICAgcmV0dXJuIGNvbF9jaGFyICsgcm93X2NoYXIKCmRlZiBnZXRfa25pZ2h0X21vdmVzKHgsIHksIE4pOgogICAgbW92ZXMgPSBbCiAgICAgICAgKHggKyAxLCB5ICsgMiksICh4ICsgMSwgeSAtIDIpLAogICAgICAgICh4IC0gMSwgeSArIDIpLCAoeCAtIDEsIHkgLSAyKSwKICAgICAgICAoeCArIDIsIHkgKyAxKSwgKHggKyAyLCB5IC0gMSksCiAgICAgICAgKHggLSAyLCB5ICsgMSksICh4IC0gMiwgeSAtIDEpCiAgICBdCiAgICB2YWxpZF9tb3ZlcyA9IFtdCiAgICBmb3IgbngsIG55IGluIG1vdmVzOgogICAgICAgIGlmIDAgPD0gbnggPCBOIGFuZCAwIDw9IG55IDwgTjoKICAgICAgICAgICAgdmFsaWRfbW92ZXMuYXBwZW5kKChueCwgbnkpKQogICAgcmV0dXJuIHZhbGlkX21vdmVzCgpkZWYgcHJpbnRfYWxsX3Nob3J0ZXN0X3BhdGhzKE4sIHN0YXJ0X3BvcywgZW5kX3Bvcyk6CiAgICBzdGFydF94LCBzdGFydF95ID0gc3RyaW5nX3RvX2Nvb3JkcyhzdGFydF9wb3MpCiAgICB0YXJnZXRfeCwgdGFyZ2V0X3kgPSBzdHJpbmdfdG9fY29vcmRzKGVuZF9wb3MpCgogICAgZGlzdGFuY2VzID0gW1stMV0gKiBOIGZvciBfIGluIHJhbmdlKE4pXQogICAgZGlzdGFuY2VzW3N0YXJ0X3hdW3N0YXJ0X3ldID0gMAogICAgCiAgICBxdWV1ZSA9IGRlcXVlKFsoc3RhcnRfeCwgc3RhcnRfeSldKQogICAgCiAgICB3aGlsZSBxdWV1ZToKICAgICAgICBjeCwgY3kgPSBxdWV1ZS5wb3BsZWZ0KCkKICAgICAgICBpZiBjeCA9PSB0YXJnZXRfeCBhbmQgY3kgPT0gdGFyZ2V0X3k6CiAgICAgICAgICAgIGJyZWFrCiAgICAgICAgCiAgICAgICAgY3VycmVudF9kaXN0ID0gZGlzdGFuY2VzW2N4XVtjeV0KICAgICAgICBmb3IgbngsIG55IGluIGdldF9rbmlnaHRfbW92ZXMoY3gsIGN5LCBOKToKICAgICAgICAgICAgaWYgZGlzdGFuY2VzW254XVtueV0gPT0gLTE6CiAgICAgICAgICAgICAgICBkaXN0YW5jZXNbbnhdW255XSA9IGN1cnJlbnRfZGlzdCArIDEKICAgICAgICAgICAgICAgIHF1ZXVlLmFwcGVuZCgobngsIG55KSkKCiAgICBpZiBkaXN0YW5jZXNbdGFyZ2V0X3hdW3RhcmdldF95XSA9PSAtMToKICAgICAgICBwcmludCgi0KjQu9GP0YXRgyDQvdC1INGW0YHQvdGD0ZQiKQogICAgICAgIHJldHVybgoKICAgIGFsbF9wYXRocyA9IFtdCiAgICAKICAgIGRlZiBmaW5kX3BhdGhzX2RmcyhjdXJyZW50X3gsIGN1cnJlbnRfeSwgY3VycmVudF9wYXRoKToKICAgICAgICBpZiBjdXJyZW50X3ggPT0gdGFyZ2V0X3ggYW5kIGN1cnJlbnRfeSA9PSB0YXJnZXRfeToKICAgICAgICAgICAgYWxsX3BhdGhzLmFwcGVuZChsaXN0KGN1cnJlbnRfcGF0aCkpCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBjdXJyZW50X2Rpc3QgPSBkaXN0YW5jZXNbY3VycmVudF94XVtjdXJyZW50X3ldCiAgICAgICAgCiAgICAgICAgZm9yIG54LCBueSBpbiBnZXRfa25pZ2h0X21vdmVzKGN1cnJlbnRfeCwgY3VycmVudF95LCBOKToKICAgICAgICAgICAgaWYgZGlzdGFuY2VzW254XVtueV0gPT0gY3VycmVudF9kaXN0ICsgMToKICAgICAgICAgICAgICAgIGN1cnJlbnRfcGF0aC5hcHBlbmQoY29vcmRzX3RvX3N0cmluZyhueCwgbnkpKQogICAgICAgICAgICAgICAgZmluZF9wYXRoc19kZnMobngsIG55LCBjdXJyZW50X3BhdGgpCiAgICAgICAgICAgICAgICBjdXJyZW50X3BhdGgucG9wKCkKCiAgICBpbml0aWFsX3BhdGggPSBbc3RhcnRfcG9zXQogICAgZmluZF9wYXRoc19kZnMoc3RhcnRfeCwgc3RhcnRfeSwgaW5pdGlhbF9wYXRoKQoKICAgIHByaW50KGYi0JzRltC90ZbQvNCw0LvRjNC90LAg0LrRltC70YzQutGW0YHRgtGMINGF0L7QtNGW0LI6IHtkaXN0YW5jZXNbdGFyZ2V0X3hdW3RhcmdldF95XX0iKQogICAgcHJpbnQoZiLQl9C90LDQudC00LXQvdC+INCy0LDRgNGW0LDQvdGC0ZbQsiDRiNC70Y/RhdGDOiB7bGVuKGFsbF9wYXRocyl9IikKICAgIGZvciBwYXRoIGluIGFsbF9wYXRoczoKICAgICAgICBwcmludCgiIC0+ICIuam9pbihwYXRoKSkKCk4gPSAxMDAwMApzdGFydCA9ICJhMSIKZW5kID0gImQ0IgoKcHJpbnRfYWxsX3Nob3J0ZXN0X3BhdGhzKE4sIHN0YXJ0LCBlbmQpCg==