题目

image.png

思路

  • 可以将不同的状态视作不同的节点,想要求最短的操作路径,那么显然BFS是首先想到的。
  • 一开始的写的一版代码太过繁琐了,可以直接用一个string来保存每个状态,交换的话,可以上下左右分别遍历,然后判断是否合法即可,之前的想法太繁琐了。简单一点就行。
  • 可以用哈希表或者红黑树保存状态,同时避免重复操作。
  • 在出队列的时候进行判断。

    代码

    ```cpp

    include

    include

    include

    include

    include

using namespace std;

int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};

int bfs(string start) { string end = “12345678x”; queue q; q.push(start); unordered_map d; d[start] = 0;

  1. while (!q.empty()) {
  2. string cur = q.front();
  3. q.pop();
  4. int distance = d[cur];
  5. if (cur == end) {
  6. return distance;
  7. }
  8. int k = cur.find('x');
  9. for (int i = 0; i < 4; i++) {
  10. int x = k / 3 + dx[i];
  11. int y = k % 3 + dy[i];
  12. if (x >= 0 && x < 3 && y >= 0 && y < 3) {
  13. swap(cur[k], cur[3 * x + y]);
  14. if (!d.count(cur)) {
  15. d[cur] = distance + 1;
  16. q.push(cur);
  17. }
  18. swap(cur[k], cur[3 * x + y]);
  19. }
  20. }
  21. }
  22. return -1;

}

int main() { string start; for (int i = 0; i < 9 ;i++) { char c; cin >> c; start += c; }

cout << bfs(start) << endl;
return 0;

} ```