Robot trong mê cung¶
Khái quát¶
Nhằm "đu trend" người người robot, nhà nhà robot, bài này mượn hình ảnh robot nhưng mục đích chính là đề cập vấn đề di chuyển giữa các ô trong lưới.
Bài toán trình bày dưới đây là một ví dụ về BFS. (1)
- Bài toán do chủ thớt tham khảo trên Internet nhưng không nhớ lấy từ trang web nào.
Bài toán¶
Yêu cầu¶
Cho một mê cung được mô phỏng bằng ma trận, hàng và cột đánh chỉ số bắt đầu từ 1. Trong đó những ô có giá trị 0 thì có thể đi vào, còn những ô có giá trị 1 thì không được đi vào.
Robot có thể di chuyển qua ô khác theo một trong bốn hướng: lên, xuống, trái và phải. Hãy tìm đường để robot di chuyển từ ô có tọa độ (r1, c1) đến ô (r2, c2).
Input¶
Output¶
Giải thích¶
Trong input:
- Dòng đầu tiên gồm sáu số là: 4 hàng và 7 cột của ma trận, 1 và 3 là toạ độ ô xuất phát, 2 và 6 là toạ độ ô kết thúc.
- Các dòng tiếp theo là các hàng của ma trận, mỗi hàng là một chuỗi ký tự mô tả mê cung.
Output là đường đi của robot từ ô xuất phát đến ô kết thúc.
Minh họa mê cung và đường đi của robot
Cách giải đề xuất¶
Ý tưởng chính¶
Dựa theo thuật toán BFS, ta thực hiện loang như sau:
-
Từ ô xuất phát
start, lần lượt xét bốn ô liền kề, ô nào robot có thể đi vào được thì đánh dấu (để truy vết đường đi sau này) và nạp vào hàng đợiq. -
Lặp lại thao tác trên cho đến khi hàng đợi
qkhông còn ô nào để duyệt hoặc ô cần duyệt là ô kết thúcfinish.
Khởi tạo¶
Khởi tạo mảng hai chiều trace dùng để đánh dấu các ô đã duyệt và truy vết đường đi.
Các phần tử trong mảng trace đều được đánh dấu là 'N', nghĩa là chưa duyệt (Not yet). Riêng ô xuất phát được đánh dấu là 'S'.
Thực hiện BFS¶
1. Khai báo hàng đợi q và nạp ô start vào hàng đợi.
2. Duyệt từng phần tử trong hàng đợi, lặp các thao tác sau:
-
Lấy ra phần tử đầu hàng đợi, gọi là ô
current. -
Nếu ô
currenttrùng với ô kết thúc thì dừng vòng lặp, robot đã đến đích. -
Lần lượt xét bốn ô liền kề với ô
currentlà: trên, dưới, trái và phải, gọi là ônext. Nếu ô liền kề thoả các điều kiện:- Vẫn còn trong phạm vi của mê cung.
- Chưa được duyệt (chưa ghé thăm).
- Có thể đi vào được.
thì đẩy ô
nextvào hàng đợi và đánh dấu ônextnày bằng bốn ký tự:'U','D','L'và'R'ứng với bốn hướng.
Output đường đi¶
Để xuất đường đi kết quả, ta dựa vào mảng trace để truy ngược bằng cách cho ô finish "lui dần" về ô xuất phát. Trong đó finish sẽ lùi "ngược hướng" với ký tự lưu trong mảng trace. Ví dụ: ký tự lưu trong trace là 'U', đi lên, thì finish sẽ đi xuống.
Mã nguồn¶
Code đầy đủ được đặt tại GitHub.