BFS-八数码

Acwing845. 八数码

一道比较难的BFS题目涉及三个过程

  1. 讲数串变成3*3的模式
  2. 进行移动(即BFS过程)
  3. 再把它还原成串
#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;
}
posted @ 2021-10-24 22:13  hcのBlog  阅读(33)  评论(0)    收藏  举报