算法基础---AcWing 845.八数码 BFS

原题链接.

题目描述

在一个3×3的网格中,1~8这8个数字和一个“x”恰好不重不漏地分布在这3×3的网格中。

例如:

1 2 3
x 4 6
7 5 8

在游戏过程中,可以把“x”与其上、下、左、右四个方向之一的数字交换(如果存在)。

我们的目的是通过交换,使得网格变为如下排列(称为正确排列):

1 2 3
4 5 6
7 8 x

例如,示例中图形就可以通过让“x”先后与右、下、右三个方向的数字交换成功得到正确排列。

交换过程如下:

1 2 3   1 2 3   1 2 3   1 2 3
x 4 6   4 x 6   4 5 6   4 5 6
7 5 8   7 5 8   7 x 8   7 8 x

现在,给你一个初始网格,请你求出得到正确排列至少需要进行多少次交换。

输入格式
输入占一行,将3×3的初始网格描绘出来。

例如,如果初始网格如下所示:

1 2 3

x 4 6

7 5 8

则输入为:1 2 3 x 4 6 7 5 8

输出格式

输出占一行,包含一个整数,表示最少交换次数。

如果不存在解决方案,则输出”-1”。

输入样例:

2  3  4  1  5  x  7  6  8 

输出样例

19

题目分析

这是一道经典的宽搜问题。

1.建图

x可以和其上下左右位置上的数字进行交换,也就是说当前位置可以变化的状态最多只会有4种,可以将当前的整个状态看成图的一个节点,可以变成的状态看成另一个节点,这两个节点之间存在一条无向边,即两个状态可互相转化。

①节点表示

将二维的表状态转换成一维的状态字符串
用集合存放图的所有结点

②边的表示

因为目标是寻找到目标状态的最短距离,故只需保存当前顶点到起始结点的最短距离即可,为了快速获取距离可以用一个将存放结点的集合转换成一个哈希表存放当前节点到起始节点的最短距离

2.问题求解

题目目标是求最少的交换次数,其实也就是两个节点间的最短路问题,故直接用bfs即可。

C++代码实现

#include 
#include 
#include 
#include 
#include 

using namespace std;

int bfs(string beg) {
     
    int dx[4] = {
     0, 1, 0, -1}, dy[4] = {
     -1, 0, 1, 0};
    string end = "12345678x";
    queue<string> q;
    unordered_map<string, int> dist;
    
    q.push(beg);
    while(!q.empty()){
     
        string now = q.front();
        q.pop();
        //找到x位置,根基其真正位置寻找可到达的状态
        int pos = now.find('x');
        int r = pos/3, c = pos%3;
        //遍历四个方位
        for(int i = 0; i < 4; ++i) {
     
            int x = r+dx[i], y = c+dy[i];
            
            if(x>=0 && x<3 && y>=0&& y<3) {
     
                string temp = now;
                int pos1 = x*3+y;
                swap(temp[pos], temp[pos1]);
                if(dist.count(temp) == 0) {
     
                    q.push(temp);
                    dist[temp] = dist[now]+1;
                    if(temp == end){
     
                        return dist[temp];
                    } 
                }
            }
        }
        
        
    }
    return -1;
}

int main() {
     
    
    char c;
    string beg;
    for(int i = 0; i < 9; ++i) {
     
        cin>>c;
        beg += c;
    }
    cout<<bfs(beg)<<endl;
    
    return 0;
}

你可能感兴趣的:(基础算法模板题,c++,算法,数据结构,bfs)