from collections import deque
KNIGHT_MOVES = [(2,1),(2,-1),(-2,1),(-2,-1),(1,2),(1,-2),(-1,2),(-1,-2)]
def queen_attacks(N, qr, qc):
attacked = [[False]*N for _ in range(N)]
for r in range(N):
attacked[r][qc] = True
for c in range(N):
attacked[qr][c] = True
for dr in (-1, 1):
for dc in (-1, 1):
r, c = qr + dr, qc + dc
while 0 <= r < N and 0 <= c < N:
attacked[r][c] = True
r += dr
c += dc
attacked[qr][qc] = True
return attacked
def find_knight_path(N, kr, kc, qr, qc, tr, tc):
for name, x, y in (("knight", kr, kc), ("queen", qr, qc), ("target", tr, tc)):
if not (0 <= x < N and 0 <= y < N):
raise IndexError(f"Координати {name} поза дошкою: ({x+1},{y+1}) у 1-based")
attacked = queen_attacks(N, qr, qc)
visited = [[[False]*2 for _ in range(N)] for __ in range(N)]
parent = {}
start_alive = 0 if (kr == qr and kc == qc) else 1
start_state = (kr, kc, start_alive)
q = deque()
q.append((kr, kc, start_alive, 0))
visited[kr][kc][start_alive] = True
parent[start_state] = None
while q:
r, c, alive, dist = q.popleft()
if (r, c) == (tr, tc):
path = []
st = (r, c, alive)
while st is not None:
path.append((st[0], st[1]))
st = parent.get(st)
path.reverse()
return path, dist
for dr, dc in KNIGHT_MOVES:
nr, nc = r + dr, c + dc
if not (0 <= nr < N and 0 <= nc < N):
continue
nalive = alive
if alive == 1:
if attacked[nr][nc] and not (nr == qr and nc == qc):
continue
if (nr == qr and nc == qc):
nalive = 0
if not visited[nr][nc][nalive]:
visited[nr][nc][nalive] = True
parent[(nr, nc, nalive)] = (r, c, alive)
q.append((nr, nc, nalive, dist + 1))
return None, -1
def draw_board(N, path, kr, kc, qr, qc, tr, tc):
board = [["." for _ in range(N)] for __ in range(N)]
if path is not None:
for i, (r, c) in enumerate(path):
board[r][c] = str(i)
def overlay(r, c, mark):
if board[r][c] == ".":
board[r][c] = mark
else:
board[r][c] = f"{mark}/{board[r][c]}"
overlay(kr, kc, "S")
overlay(qr, qc, "Q")
overlay(tr, tc, "T")
print("\nШахівниця (позиції у форматі MARK/num або num):")
for r in range(N):
row_str = ""
for c in range(N):
cell = board[r][c]
row_str += cell.center(6)
print(row_str)
print()
def main():
try:
N = int(input("Введіть N (розмір дошки, 1..100): ").strip())
except Exception:
print("Некоректне N")
return
if N < 1 or N > 100:
print("N має бути в діапазоні 1..100")
return
def read_coord(name):
try:
s = input(f"Введіть {name} (рядок і стовпець, 1-based, через пробіл): ").strip().split()
if len(s) < 2:
raise ValueError("Потрібні два числа")
r = int(s[0]); c = int(s[1])
return r-1, c-1
except Exception as e:
raise ValueError(f"Помилка вводу для {name}: {e}")
try:
kr, kc = read_coord("координати коня")
qr, qc = read_coord("координати ферзя")
tr, tc = read_coord("координати цілі")
except ValueError as e:
print(e)
return
print(f"Ви ввели (1-based): N={N}; K=({kr+1},{kc+1}); Q=({qr+1},{qc+1}); T=({tr+1},{tc+1})")
for name, (x,y) in (("Кінь",(kr,kc)),("Ферзь",(qr,qc)),("Ціль",(tr,tc))):
if not (0 <= x < N and 0 <= y < N):
print(f"{name} має координати поза дошкою: ({x+1},{y+1})")
return
path, moves = find_knight_path(N, kr, kc, qr, qc, tr, tc)
if moves == -1:
print("Шлях не знайдено — кінь не може дістатися до цілі з урахуванням правил.")
else:
print(f"Мінімальна кількість ходів: {moves}")
print("Шлях (0-based у tuple):")
print(path)
draw_board(N, path, kr, kc, qr, qc, tr, tc)
if __name__ == "__main__":
main()
ZnJvbSBjb2xsZWN0aW9ucyBpbXBvcnQgZGVxdWUKCktOSUdIVF9NT1ZFUyA9IFsoMiwxKSwoMiwtMSksKC0yLDEpLCgtMiwtMSksKDEsMiksKDEsLTIpLCgtMSwyKSwoLTEsLTIpXQoKZGVmIHF1ZWVuX2F0dGFja3MoTiwgcXIsIHFjKToKICAgIGF0dGFja2VkID0gW1tGYWxzZV0qTiBmb3IgXyBpbiByYW5nZShOKV0KICAgIGZvciByIGluIHJhbmdlKE4pOgogICAgICAgIGF0dGFja2VkW3JdW3FjXSA9IFRydWUKICAgIGZvciBjIGluIHJhbmdlKE4pOgogICAgICAgIGF0dGFja2VkW3FyXVtjXSA9IFRydWUKICAgIGZvciBkciBpbiAoLTEsIDEpOgogICAgICAgIGZvciBkYyBpbiAoLTEsIDEpOgogICAgICAgICAgICByLCBjID0gcXIgKyBkciwgcWMgKyBkYwogICAgICAgICAgICB3aGlsZSAwIDw9IHIgPCBOIGFuZCAwIDw9IGMgPCBOOgogICAgICAgICAgICAgICAgYXR0YWNrZWRbcl1bY10gPSBUcnVlCiAgICAgICAgICAgICAgICByICs9IGRyCiAgICAgICAgICAgICAgICBjICs9IGRjCiAgICBhdHRhY2tlZFtxcl1bcWNdID0gVHJ1ZQogICAgcmV0dXJuIGF0dGFja2VkCgpkZWYgZmluZF9rbmlnaHRfcGF0aChOLCBrciwga2MsIHFyLCBxYywgdHIsIHRjKToKICAgIGZvciBuYW1lLCB4LCB5IGluICgoImtuaWdodCIsIGtyLCBrYyksICgicXVlZW4iLCBxciwgcWMpLCAoInRhcmdldCIsIHRyLCB0YykpOgogICAgICAgIGlmIG5vdCAoMCA8PSB4IDwgTiBhbmQgMCA8PSB5IDwgTik6CiAgICAgICAgICAgIHJhaXNlIEluZGV4RXJyb3IoZiLQmtC+0L7RgNC00LjQvdCw0YLQuCB7bmFtZX0g0L/QvtC30LAg0LTQvtGI0LrQvtGOOiAoe3grMX0se3krMX0pINGDIDEtYmFzZWQiKQoKICAgIGF0dGFja2VkID0gcXVlZW5fYXR0YWNrcyhOLCBxciwgcWMpCgogICAgdmlzaXRlZCA9IFtbW0ZhbHNlXSoyIGZvciBfIGluIHJhbmdlKE4pXSBmb3IgX18gaW4gcmFuZ2UoTildCiAgICBwYXJlbnQgPSB7fQoKICAgIHN0YXJ0X2FsaXZlID0gMCBpZiAoa3IgPT0gcXIgYW5kIGtjID09IHFjKSBlbHNlIDEKICAgIHN0YXJ0X3N0YXRlID0gKGtyLCBrYywgc3RhcnRfYWxpdmUpCiAgICBxID0gZGVxdWUoKQogICAgcS5hcHBlbmQoKGtyLCBrYywgc3RhcnRfYWxpdmUsIDApKQogICAgdmlzaXRlZFtrcl1ba2NdW3N0YXJ0X2FsaXZlXSA9IFRydWUKICAgIHBhcmVudFtzdGFydF9zdGF0ZV0gPSBOb25lCgogICAgd2hpbGUgcToKICAgICAgICByLCBjLCBhbGl2ZSwgZGlzdCA9IHEucG9wbGVmdCgpCiAgICAgICAgaWYgKHIsIGMpID09ICh0ciwgdGMpOgogICAgICAgICAgICBwYXRoID0gW10KICAgICAgICAgICAgc3QgPSAociwgYywgYWxpdmUpCiAgICAgICAgICAgIHdoaWxlIHN0IGlzIG5vdCBOb25lOgogICAgICAgICAgICAgICAgcGF0aC5hcHBlbmQoKHN0WzBdLCBzdFsxXSkpCiAgICAgICAgICAgICAgICBzdCA9IHBhcmVudC5nZXQoc3QpCiAgICAgICAgICAgIHBhdGgucmV2ZXJzZSgpCiAgICAgICAgICAgIHJldHVybiBwYXRoLCBkaXN0CgogICAgICAgIGZvciBkciwgZGMgaW4gS05JR0hUX01PVkVTOgogICAgICAgICAgICBuciwgbmMgPSByICsgZHIsIGMgKyBkYwogICAgICAgICAgICBpZiBub3QgKDAgPD0gbnIgPCBOIGFuZCAwIDw9IG5jIDwgTik6CiAgICAgICAgICAgICAgICBjb250aW51ZQoKICAgICAgICAgICAgbmFsaXZlID0gYWxpdmUKICAgICAgICAgICAgaWYgYWxpdmUgPT0gMToKICAgICAgICAgICAgICAgIGlmIGF0dGFja2VkW25yXVtuY10gYW5kIG5vdCAobnIgPT0gcXIgYW5kIG5jID09IHFjKToKICAgICAgICAgICAgICAgICAgICBjb250aW51ZQogICAgICAgICAgICAgICAgaWYgKG5yID09IHFyIGFuZCBuYyA9PSBxYyk6CiAgICAgICAgICAgICAgICAgICAgbmFsaXZlID0gMAoKICAgICAgICAgICAgaWYgbm90IHZpc2l0ZWRbbnJdW25jXVtuYWxpdmVdOgogICAgICAgICAgICAgICAgdmlzaXRlZFtucl1bbmNdW25hbGl2ZV0gPSBUcnVlCiAgICAgICAgICAgICAgICBwYXJlbnRbKG5yLCBuYywgbmFsaXZlKV0gPSAociwgYywgYWxpdmUpCiAgICAgICAgICAgICAgICBxLmFwcGVuZCgobnIsIG5jLCBuYWxpdmUsIGRpc3QgKyAxKSkKCiAgICByZXR1cm4gTm9uZSwgLTEKCmRlZiBkcmF3X2JvYXJkKE4sIHBhdGgsIGtyLCBrYywgcXIsIHFjLCB0ciwgdGMpOgogICAgYm9hcmQgPSBbWyIuIiBmb3IgXyBpbiByYW5nZShOKV0gZm9yIF9fIGluIHJhbmdlKE4pXQoKICAgIGlmIHBhdGggaXMgbm90IE5vbmU6CiAgICAgICAgZm9yIGksIChyLCBjKSBpbiBlbnVtZXJhdGUocGF0aCk6CiAgICAgICAgICAgIGJvYXJkW3JdW2NdID0gc3RyKGkpCgogICAgZGVmIG92ZXJsYXkociwgYywgbWFyayk6CiAgICAgICAgaWYgYm9hcmRbcl1bY10gPT0gIi4iOgogICAgICAgICAgICBib2FyZFtyXVtjXSA9IG1hcmsKICAgICAgICBlbHNlOgogICAgICAgICAgICBib2FyZFtyXVtjXSA9IGYie21hcmt9L3tib2FyZFtyXVtjXX0iCgogICAgb3ZlcmxheShrciwga2MsICJTIikKICAgIG92ZXJsYXkocXIsIHFjLCAiUSIpCiAgICBvdmVybGF5KHRyLCB0YywgIlQiKQoKICAgIHByaW50KCJcbtCo0LDRhdGW0LLQvdC40YbRjyAo0L/QvtC30LjRhtGW0Zcg0YMg0YTQvtGA0LzQsNGC0ZYgTUFSSy9udW0g0LDQsdC+IG51bSk6IikKICAgIGZvciByIGluIHJhbmdlKE4pOgogICAgICAgIHJvd19zdHIgPSAiIgogICAgICAgIGZvciBjIGluIHJhbmdlKE4pOgogICAgICAgICAgICBjZWxsID0gYm9hcmRbcl1bY10KICAgICAgICAgICAgcm93X3N0ciArPSBjZWxsLmNlbnRlcig2KQogICAgICAgIHByaW50KHJvd19zdHIpCiAgICBwcmludCgpCgpkZWYgbWFpbigpOgogICAgdHJ5OgogICAgICAgIE4gPSBpbnQoaW5wdXQoItCS0LLQtdC00ZbRgtGMIE4gKNGA0L7Qt9C80ZbRgCDQtNC+0YjQutC4LCAxLi4xMDApOiAiKS5zdHJpcCgpKQogICAgZXhjZXB0IEV4Y2VwdGlvbjoKICAgICAgICBwcmludCgi0J3QtdC60L7RgNC10LrRgtC90LUgTiIpCiAgICAgICAgcmV0dXJuCiAgICBpZiBOIDwgMSBvciBOID4gMTAwOgogICAgICAgIHByaW50KCJOINC80LDRlCDQsdGD0YLQuCDQsiDQtNGW0LDQv9Cw0LfQvtC90ZYgMS4uMTAwIikKICAgICAgICByZXR1cm4KCiAgICBkZWYgcmVhZF9jb29yZChuYW1lKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHMgPSBpbnB1dChmItCS0LLQtdC00ZbRgtGMIHtuYW1lfSAo0YDRj9C00L7QuiDRliDRgdGC0L7QstC/0LXRhtGMLCAxLWJhc2VkLCDRh9C10YDQtdC3INC/0YDQvtCx0ZbQuyk6ICIpLnN0cmlwKCkuc3BsaXQoKQogICAgICAgICAgICBpZiBsZW4ocykgPCAyOgogICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigi0J/QvtGC0YDRltCx0L3RliDQtNCy0LAg0YfQuNGB0LvQsCIpCiAgICAgICAgICAgIHIgPSBpbnQoc1swXSk7IGMgPSBpbnQoc1sxXSkKICAgICAgICAgICAgcmV0dXJuIHItMSwgYy0xCiAgICAgICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKGYi0J/QvtC80LjQu9C60LAg0LLQstC+0LTRgyDQtNC70Y8ge25hbWV9OiB7ZX0iKQoKICAgIHRyeToKICAgICAgICBrciwga2MgPSByZWFkX2Nvb3JkKCLQutC+0L7RgNC00LjQvdCw0YLQuCDQutC+0L3RjyIpCiAgICAgICAgcXIsIHFjID0gcmVhZF9jb29yZCgi0LrQvtC+0YDQtNC40L3QsNGC0Lgg0YTQtdGA0LfRjyIpCiAgICAgICAgdHIsIHRjID0gcmVhZF9jb29yZCgi0LrQvtC+0YDQtNC40L3QsNGC0Lgg0YbRltC70ZYiKQogICAgZXhjZXB0IFZhbHVlRXJyb3IgYXMgZToKICAgICAgICBwcmludChlKQogICAgICAgIHJldHVybgoKICAgIHByaW50KGYi0JLQuCDQstCy0LXQu9C4ICgxLWJhc2VkKTogTj17Tn07IEs9KHtrcisxfSx7a2MrMX0pOyBRPSh7cXIrMX0se3FjKzF9KTsgVD0oe3RyKzF9LHt0YysxfSkiKQoKICAgIGZvciBuYW1lLCAoeCx5KSBpbiAoKCLQmtGW0L3RjCIsKGtyLGtjKSksKCLQpNC10YDQt9GMIiwocXIscWMpKSwoItCm0ZbQu9GMIiwodHIsdGMpKSk6CiAgICAgICAgaWYgbm90ICgwIDw9IHggPCBOIGFuZCAwIDw9IHkgPCBOKToKICAgICAgICAgICAgcHJpbnQoZiJ7bmFtZX0g0LzQsNGUINC60L7QvtGA0LTQuNC90LDRgtC4INC/0L7Qt9CwINC00L7RiNC60L7RjjogKHt4KzF9LHt5KzF9KSIpCiAgICAgICAgICAgIHJldHVybgoKICAgIHBhdGgsIG1vdmVzID0gZmluZF9rbmlnaHRfcGF0aChOLCBrciwga2MsIHFyLCBxYywgdHIsIHRjKQogICAgaWYgbW92ZXMgPT0gLTE6CiAgICAgICAgcHJpbnQoItCo0LvRj9GFINC90LUg0LfQvdCw0LnQtNC10L3QviDigJQg0LrRltC90Ywg0L3QtSDQvNC+0LbQtSDQtNGW0YHRgtCw0YLQuNGB0Y8g0LTQviDRhtGW0LvRliDQtyDRg9GA0LDRhdGD0LLQsNC90L3Rj9C8INC/0YDQsNCy0LjQuy4iKQogICAgZWxzZToKICAgICAgICBwcmludChmItCc0ZbQvdGW0LzQsNC70YzQvdCwINC60ZbQu9GM0LrRltGB0YLRjCDRhdC+0LTRltCyOiB7bW92ZXN9IikKICAgICAgICBwcmludCgi0KjQu9GP0YUgKDAtYmFzZWQg0YMgdHVwbGUpOiIpCiAgICAgICAgcHJpbnQocGF0aCkKICAgICAgICBkcmF3X2JvYXJkKE4sIHBhdGgsIGtyLCBrYywgcXIsIHFjLCB0ciwgdGMpCgppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOgogICAgbWFpbigpCg==