BFS-八數碼
阿新 • • 發佈:2021-10-24
Acwing845. 八數碼
一道比較難的BFS題目涉及三個過程
- 講數串變成3*3的模式
- 進行移動(即BFS過程)
- 再把它還原成串
#include <iostream> #include <cstring> #include <unordered_map> #include <queue> using namespace std; int bfs(string start) { queue<string> q; // BFS需要維護一個佇列來儲存每一步的狀態 unordered_map<string, int> d; // 建立一個string到int的對映用來計算步數 q.push(start); // 出狀態入隊 d[start] = 0; // 初始狀態步數記錄為0 int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1}; string end = "12345678x"; // 記錄最終狀態 // BFS while(q.size()) { string t = q.front(); q.pop(); // 取最近狀態 if (t == end) return d[t]; // 返回答案 int distance = d[t]; // 記錄當前距離 int k = t.find('x'); // find()用於尋找x在字串中的位置,比如123x返回3 // 對於n行m列且座標從0開始一維轉換二維座標,k為一維座標位置 // 橫座標x為 x = k / n, 縱座標y為 y = k % n; int x = k / 3, y = k % 3; for (int i = 0; i < 4; i ++) { int a = x + dx[i], b = y + dy[i]; if (a >= 0 && a < 3 && b >= 0 && b < 3) { // 在範圍內則交換 swap(t[a * 3 + b], t[k]); // 該狀態沒有被找到過則記錄到達該狀態的距離,並講該狀態入隊 if(!d.count(t)) { d[t] = distance + 1; q.push(t); } // 還原,進行下一個方向的操作 swap(t[a * 3 + b], t[k]); } } } return -1; } int main() { char c; string start; for(int i = 0; i < 9; i ++) { cin >> c; start += c; } cout << bfs(start) << endl; return 0; }