Đi tiếp hoặc quay về bước trước
```python
def solveMaze(maze, m, n, x, y, sol, goals=None):
if not (0 <= x < n and 0 <= y < m):
return False
if maze[y][x] != 0 or sol[y][x] == 1:
return False
if goals is None:
goals = {(n - 1, m - 1)}
sol[y][x] = 1
if (x, y) in goals:
return True
for dx, dy in [(1, 0), (0, 1), (-1, 0), (0, -1)]:
if solveMaze(maze, m, n, x + dx, y + dy, sol, goals):
return True
sol[y][x] = 0
return False
```
Mỗi lời gọi xét một ô. Trước hết kiểm biên, tường và việc ô đã nằm trong đường hiện tại; sau đó mới đánh dấu sol[y][x]=1. Nếu gặp đích thì trả True. Nếu chưa tới đích, thử phải, xuống, trái, lên theo thứ tự các cặp (dx,dy).
Một lời gọi con thành công làm các mức trước trả True ngay, giữ nguyên vết đường. Chỉ khi cả bốn hướng thất bại mới đặt lại 0 và trả False. Ô bị bỏ khỏi nhánh này vẫn có thể được thử trong một nhánh khác. Không đánh dấu sẽ dễ đi vòng lại các ô cũ.
Nhánh đã thử chưa chắc thuộc kết quả
Trong mẫu 4×5, từ (0,0) thuật toán thử sang phải tới (1,0),(2,0). Đường này cụt vì các ô còn lại kề nó là tường hoặc đã thuộc tiền tố. Hai dấu ở (2,0),(1,0) được bỏ khi quay lui.
Sau đó đi xuống (0,1),(0,2), rồi sang phải theo hàng 2 và xuống đích (4,3). Kết quả:
```text
1 0 0 0 0
1 0 0 0 0
1 1 1 1 1
0 0 0 0 1
```
Đây là đường tìm được theo thứ tự thử, không có cam kết là ngắn nhất. sol chỉ giữ vết của đường thành công, không phải mọi ô từng được thử.
Chạy và kiểm vết theo từng ô
Đặt mã và tệp mẫu trong cùng thư mục, rồi chạy:
```text
python3 g11-cs-me-cung.py g11-cs-me-cung.inp --output maze.out
```
Cần nhận kích thước 4 hàng 5 cột, xuất phát (0,0), cùng ma trận vết trên màn hình và trong maze.out. Kiểm đầu/đích có dấu 1, mọi ô trên đường ứng với maze bằng 0 và mỗi bước chỉ đổi hàng hoặc cột một đơn vị.
Tệp kết quả được ghi bằng chế độ w, thay nội dung cũ. Nếu không có đường, bản thực hành thông báo và ghi tệp rỗng để tránh đọc nhầm kết quả lượt trước. Tệp kết quả phải khác tệp đầu vào. Bản chạy một đường nhận tối đa 60 ô để giữ việc thực hành trong lưới nhỏ.
Bài luyện
Khi cả bốn hướng từ ô hiện tại thất bại, cần làm gì?
Thử đủ hướng thất bại chưa tạo đường tới đích.
Dữ liệu maze cần giữ nguyên.
Bỏ lựa chọn của nhánh không thành công.
Ô ngõ cụt không thuộc đường tìm được.
Lời giải
Không có đường tiếp từ ô ấy trong nhánh hiện tại. Bỏ dấu của ô và trả False để mức trước thử hướng khác; không thay cấu trúc mê cung.
Bài luyện
Vì sao kiểm 0<=x<n và 0<=y<m trước maze[y][x]?
Đích vẫn là điều kiện riêng.
Ô trong lưới vẫn có thể là tường.
Bài chỉ cho đi kề cạnh.
Tọa độ phải hợp lệ trước khi đọc ô.
Lời giải
Lời gọi thử một hướng có thể đưa tọa độ ra ngoài lưới. Chặn trước truy cập tránh IndexError ở phía vượt cuối và tránh Python đọc nhầm hàng/cột cuối khi chỉ số âm.
Bài luyện
Thứ tự thử phải–xuống–trái–lên bảo đảm điều gì khi hàm trả True?
Hàm dừng ở nhánh thành công đầu tiên.
Thuật toán này không so độ dài các nghiệm.
Các nhánh sau chưa chắc đã được thử.
Chỉ cần tới đích, không cần phủ mọi ô mở.
Lời giải
True được trả ngay khi có một chuỗi bước hợp lệ tới đích. Không có bước so sánh độ dài hoặc tiếp tục đủ mọi nghiệm, nên chỉ kết luận đã tìm một đường.
Đang học