Dấu vết là thứ tự bước đi
Trên bàn cờ 8×8, từ vị trí ban đầu cần tìm hành trình qua mọi ô đúng một lần. Bài không yêu cầu bước cuối quay về ô đầu.
board dùng −1 cho ô chưa đi; ô xuất phát mang số 0, các ô sau mang 1…63. Trong tệp này dùng tên row cho hàng, col cho cột và truy cập board[row][col], tránh nhầm với x,y của bài mê cung.
Quân Mã đi lệch 2 hàng và 1 cột, hoặc 1 hàng và 2 cột, theo các dấu âm/dương. Có tối đa tám ứng viên; ở biên hoặc gần ô đã đi thì số lựa chọn hợp lệ ít hơn.
Chỉ đi vào ô trong bàn cờ và chưa đi
```python
def isOK(row, col, board):
n = len(board)
return 0 <= row < n and 0 <= col < n and board[row][col] == -1
```
Kiểm biên trước khi đọc board[row][col]. Dấu−1 là điều kiện chọn ô tiếp theo; số 0 vẫn là một ô đã đi, không phải ô trống.
Đánh dấu, đi tiếp và khôi phục
```python
def knightTraverse(n, board, row, col, pos):
if pos == n * n:
return True
move_row = [2, 1, -1, -2, -2, -1, 1, 2]
move_col = [1, 2, 2, 1, -1, -2, -2, -1]
for i in range(8):
next_row = row + move_row[i]
next_col = col + move_col[i]
if isOK(next_row, next_col, board):
board[next_row][next_col] = pos
if knightTraverse(n, board, next_row, next_col, pos + 1):
return True
board[next_row][next_col] = -1
return False
```
Khởi tạo board toàn −1, đặt board[row][col]=0 ở vị trí xuất phát, gọi với pos=1. pos là số thứ tự sẽ gán cho ô kế tiếp. Khi pos==n*n, tất cả n*n ô đã được đánh số 0…n*n−1 nên trả True.
Nếu nhánh con thất bại, trả ô vừa thử về −1 rồi xét ứng viên khác. Nếu thành công thì giữ ma trận và trả True qua các mức. Thứ tự tám nước trong tệp theo SGV; không bảo đảm thời gian chạy ngắn cho mọi điểm xuất phát.
Kiểm đủ 64 ô và từng nước đi
Chạy:
```text
python3 g11-cs-ma-di-tuan.py 8 0 0
```
Cần nhận tám dòng, mỗi dòng tám số; các giá trị 0…63 mỗi số đúng một lần và ô (hàng 0,cột 0) có số 0. Với từng cặp số liên tiếp, kiểm độ chênh hàng/cột là (2,1) hoặc (1,2) theo trị tuyệt đối. Chỉ có đủ số khác nhau chưa bảo đảm các nước đều hợp lệ.
Tệp kết quả mẫu là một hành trình đã kiểm, không phải kết quả duy nhất. Thời gian quay lui có thể dài tùy điểm xuất phát; chạy lâu chưa phải bằng chứng không có hành trình. Bản thực hành nhận n từ 1 đến 8 để có thể thử thêm trường hợp nhỏ, nhưng nhiệm vụ trong bài vẫn là bàn cờ 8×8.
Bài luyện
Trong board, ô mang số 0 có ý nghĩa gì?
Ô chưa đi dùng −1.
Bài Mã đi tuần không có tường.
Chỉ số thứ tự chạy0…63.
Ô đầu được đánh số 0 trước lời gọi đệ quy.
Lời giải
Khởi tạo mọi ô bằng−1 rồi gán 0 cho điểm xuất phát. Do đó 0 cũng là dấu đã đi; không được chọn lại ô ấy như một ô trống.
Bài luyện
Độ chênh tuyệt đối nào là một nước Mã hợp lệ?
Đúng một trong hai dạng (2,1) hoặc (1,2).
Đây là bước chéo một ô.
Hai độ chênh đều 2 không phải nước Mã.
Mã không đi thẳng ba ô.
Lời giải
Một nước Mã đổi hai ô ở một chiều và một ô ở chiều kia. Vì vậy độ chênh (2,1) hợp lệ, còn các cặp còn lại không thuộc tám nước được sinh.
Bài luyện
Nhánh con thất bại thì vì sao đặt ô vừa thử về −1?
Chưa đi hết bàn cờ thì không ghi nghiệm.
Mỗi mức khôi phục ô mà nó vừa đánh dấu.
Đã trả về trạng thái chưa đi.
Chỉ khôi phục ô mới thử của mức hiện tại.
Lời giải
Dấu thứ tự của ô được đặt để thử một hướng. Nếu hướng đó không dẫn tới hành trình đầy đủ, trả ô về chưa đi giúp nhánh khác còn lựa chọn đúng; không thay điểm xuất phát đã đánh số 0.
Đang học