Robot trong mê cung¶
Khái quát¶
Nhằm "đu trend" người người robot, nhà nhà robot, bài này nhắc đến robot nhưng mục đích chính là đề cập đến việc 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 áp dụng trên ma trận. (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, chỉ số hàng và cột được đánh thứ tự từ 1. Trong mê cung, những ô có giá trị 0 thì có thể đi vào, còn những ô có giá trị 1 thì không thể.
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ừ ô (r1, c1) đến ô (r2, c2).
Input:
Output:
Giải thích:
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 vào mảngtracevà 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¶
Khai báo mảng hai chiều trace có kích thước tương tự mê cung maze, dùng để đánh dấu các ô đã duyệt và truy vết đường đi.
Khởi tạo trace với mọi phần tử đều được là 'N' (Not yet). Riêng ô xuất phát start 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. Dùng vòng lặp 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 ôfinishthì 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, chưa đánh dấu)
- Có thể đi vào được
thì đẩy ô
nextvào hàng đợi và đánh dấu ônextnày bằng một trong bốn ký tự:'U','D','L'và'R'ứng với bốn hướng.
Xuất output¶
Ta dựa vào mảng trace để truy ngược bằng cách cho ô finish "lùi dần" về ô start. Trong đó, finish sẽ lùi "ngược hướng" với ký tự lưu trong 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.