CSES - Knight's Tour | Hành trình của quân mã

Xem PDF

Điểm: 2200 (p) Thời gian: 1.0s Bộ nhớ: 512M Input: bàn phím Output: màn hình

Với vị trí xuất phát của một quân mã trên bàn cờ \(8 \times 8\), nhiệm vụ của bạn là tìm một chuỗi các nước đi sao cho nó truy cập đúng một lần vào mỗi ô vuông.

Trong mỗi lần di chuyển, quân mã có thể di chuyển hai bước theo chiều ngang và một bước theo chiều dọc, hoặc một bước theo chiều ngang và hai bước theo chiều dọc.

Input

  • Dòng duy nhất là hai số nguyên \(x\)\(y\): vị trí xuất phát của quân mã.

Output

  • In một lưới hiển thị cách di chuyển của quân mã (theo ví dụ). Bạn có thể in bất kỳ giải pháp hợp lệ nào.

Constraints

  • \(1 \leq x, y \leq 8\)

Example

Test 1

Input
2 1
Output
8 1 10 13 6 3 20 17
11 14 7 2 19 16 23 4
26 9 12 15 24 5 18 21
49 58 25 28 51 22 33 30
40 27 50 59 32 29 52 35
57 48 41 44 37 34 31 62
42 39 46 55 60 63 36 53
47 56 43 38 45 54 61 64

Bình luận


  • -1
    rock    7:09 p.m. 23 Tháng 10, 2024

    const
    N = 8;
    var
    board: array[1..N, 1..N] of integer;
    xMove: array[1..8] of integer = (2, 1, -1, -2, -2, -1, 1, 2);
    yMove: array[1..8] of integer = (1, 2, 2, 1, -1, -2, -2, -1);
    i, j: integer;

    procedure printSolution;
    var
    x, y: integer;
    begin
    for x := 1 to N do
    begin
    for y := 1 to N do
    write(board[x, y]:3, ' ');
    writeln;
    end;
    end;

    function isSafe(x, y: integer): boolean;
    begin
    isSafe := (x >= 1) and (x <= N) and (y >= 1) and (y <= N) and (board[x, y] = 0);
    end;

    function getDegree(x, y: integer): integer;
    var
    count, k, nextX, nextY: integer;
    begin
    count := 0;
    for k := 1 to 8 do
    begin
    nextX := x + xMove[k];
    nextY := y + yMove[k];
    if isSafe(nextX, nextY) then
    count := count + 1;
    end;
    getDegree := count;
    end;

    function solveKTUtil(x, y, movei: integer): boolean;
    var
    k, minDegree, nextX, nextY, bestX, bestY, degree: integer;
    begin
    if movei = N * N + 1 then
    exit(True);

    minDegree := 9;
    bestX := -1;
    bestY := -1;

    for k := 1 to 8 do
    begin
    nextX := x + xMove[k];
    nextY := y + yMove[k];
    if isSafe(nextX, nextY) then
    begin
    degree := getDegree(nextX, nextY);
    if degree < minDegree then
    begin
    minDegree := degree;
    bestX := nextX;
    bestY := nextY;
    end;
    end;
    end;

    if bestX <> -1 then
    begin
    board[bestX, bestY] := movei;
    if solveKTUtil(bestX, bestY, movei + 1) then
    exit(True)
    else
    board[bestX, bestY] := 0;
    end;

    exit(False);
    end;

    procedure solveKT(xStart, yStart: integer);
    begin
    for i := 1 to N do
    for j := 1 to N do
    board[i, j] := 0;

    board[xStart, yStart] := 1;

    if not solveKTUtil(xStart, yStart, 2) then
    writeln('Me may beo haha dung la mot con ga')
    else
    printSolution;
    end;

    var
    xStart, yStart: integer;

    begin
    readln(xStart, yStart);
    solveKT(xStart, yStart);
    end.
    Sai chỗ nào mà tui dc có 500/2200 vậy(pascal)


    • 0
      Youtuber_TWK    3:06 p.m. 2 Tháng 10, 2024

      Tui thích chơi cờ vua nhưng làm bài này khó quá ;-;


      • 1
        blinh    12:41 a.m. 28 Tháng 8, 2024 chỉnh sửa 2

        hint: hãy đi mã ở ô có ít bước tiếp đi tiếp theo nhất
        độ phức tạp: O(8*8)?


        • 1
          lehongduc    8:39 a.m. 22 Tháng 6, 2024

          bài này quay lui dc ko ta 🙂

          1 phản hồi

          • 0
            kingofgame    12:22 a.m. 29 Tháng 5, 2024

            • 0
              blinh    12:34 a.m. 28 Tháng 4, 2024

              cuối cùng đã giải được bằng python sau 61 dòng :((

              1 phản hồi

              • 0
                ducmanhhb15    2:46 p.m. 6 Tháng 7, 2023

                admin có thể xem qua code và giúp e được k ạ, luôn bị bị time 2 test @@