In ma trận khi gặp nghiệm
```python
def printmaze(outmaze):
for row in outmaze:
print(*row)
```
Đường đi đơn không đi qua một ô hai lần. Bài này liệt kê mọi đường đi đơn từ điểm xuất phát đến đích, không yêu cầu các đường có cùng độ dài. Nếu tới đích thì ghi nhận đường và không đi tiếp ra khỏi đích trong nhánh ấy.
Quay lui sau cả nhánh thành công
```python
def allMaze(maze, m, n, x, y, sol, path, goals=None, mark_walls=False):
global npaths
if not (0 <= x < n and 0 <= y < m):
return
if maze[y][x] != 0 or sol[y][x] == 1:
return
if goals is None:
goals = {(n - 1, m - 1)}
sol[y][x] = 1
path.append((x, y))
if (x, y) in goals:
npaths += 1
print(f'Đường {npaths}: {path}')
printmaze(wall_view(maze, sol, mark_walls))
else:
for dx, dy in [(1, 0), (0, 1), (-1, 0), (0, -1)]:
allMaze(maze, m, n, x + dx, y + dy, sol, path, goals, mark_walls)
path.pop()
sol[y][x] = 0
```
Đặt npaths=0, tạo sol toàn 0 và path=[] trước lời gọi gốc. Hàm wall_view của bài trước chỉ tạo bản trình bày. Mỗi bước thêm tọa độ vào path để ghi cả thứ tự đi; ma trận vết chỉ cho tập ô đã đi, chưa biểu diễn đầy đủ thứ tự các bước.
Khác solveMaze, hàm không truyền True để dừng cả cây ở nghiệm đầu. Sau mỗi nhánh, kể cả nhánh tới đích, đều pop tọa độ và đặt dấu ô về 0. Nhờ vậy mức trước thử được đường khác; dấu chỉ cấm lặp ô trong đường hiện tại, không cấm mọi đường về sau.
Hai đường trên lưới 2×2
Mẫu nhỏ gồm bốn ô mở. Chạy:
```text
python3 g11-cs-me-cung.py g11-cs-me-cung-nho.inp --tat-ca
```
Cần nhận hai đường theo thứ tự thử:
| Đường | Các tọa độ theo thứ tự |
|---|---|
| 1 | (0,0)→(1,0)→(1,1) |
| 2 | (0,0)→(0,1)→(1,1) |
Mỗi đường có một ma trận vết kèm theo; cuối cùng tổng bằng 2. Kiểm từng đường không lặp tọa độ, các bước kề cạnh và chỉ đi qua maze bằng 0. Sau khi liệt kê xong, sol trở lại toàn 0 và path rỗng, gồm cả dấu ở đích.
Tệp thực hành in trực tiếp các đường, không nhận --output trong chế độ này. Chỉ nhận tối đa 16 ô vì số đường tăng rất nhanh, kể cả khi lưới nhỏ. Không thay tất cả đường bằng chỉ các đường ngắn nhất.
Bài luyện
Vì sao không trả True để kết thúc toàn bộ sau đường đầu tiên?
Yêu cầu tìm tất cả khác với tìm một.
Đường đầu tiên vẫn có thể hợp lệ.
Mọi đường được tìm đều kết thúc ở đích.
Mê cung không đổi.
Lời giải
Trả True qua các mức sẽ dừng ngay như solveMaze. Muốn tìm tất cả, cần ghi nghiệm rồi quay lui và thử tiếp các lựa chọn còn lại.
Bài luyện
Sau khi allMaze liệt kê xong lưới 2×2, trạng thái nào đúng?
path chỉ chứa một tiền tố tại từng thời điểm.
Mỗi mức đã bỏ lựa chọn nó thêm, kể cả đích.
Hàm liệt kê khôi phục sau mỗi nghiệm.
Ô đích cũng cần bỏ dấu khi quay về.
Lời giải
Mỗi ô được đánh dấu và append khi đi vào, rồi pop và đặt lại 0 trước khi lời gọi kết thúc. Vì thế lời gọi gốc khôi phục toàn bộ trạng thái ban đầu.
Bài luyện
Đường đi đơn có điều kiện nào?
Độ dài các đường có thể khác nhau.
Chỉ cần nối điểm xuất phát tới đích.
Dấu vết hiện tại loại bước quay lại ô đã có.
Các đường khác vẫn có thể dùng chung ô.
Lời giải
Một đường đi đơn không lặp đỉnh, ở đây là ô lưới. Khi quay lui, dấu được bỏ để ô vẫn được dùng trong một đường khác; không thêm yêu cầu ngắn nhất hoặc phủ mọi ô.
Bài luyện
Vì sao tệp thực hành in thêm dãy tọa độ có thứ tự?
Mọi bước vẫn phải nằm ở ô mở.
npaths vẫn đếm nghiệm.
Các đường có thể có vết khác nhau.
Ma trận chỉ đánh dấu ô thuộc đường.
Lời giải
Dãy tọa độ cho biết đi từ ô nào sang ô nào, giúp kiểm kề cạnh, đầu/đích và việc không lặp ô. Ma trận 0/1 chỉ cho biết ô có nằm trong vết, nên cần phân biệt hai dạng biểu diễn.
Đang học