c++算法学习笔记 (7) BFS

简介: c++算法学习笔记 (7) BFS

1.走迷宫

#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
typedef pair<int, int> PII;
const int N = 105;
int n, m;
int g[N][N]; // 存图
int d[N][N]; // 每个点到起点的距离
queue<PII> q[N * N];
 
int bfs()
{
    q->push(make_pair(0, 0));
    memset(d, -1, sizeof d);
    d[0][0] = 0;
    int dx[4] = {-1, 0, 1, 0};
    int dy[4] = {0, 1, 0, -1};
    while (!q->empty())
    {
        PII t = q->front(); // 取队头
        q->pop();
        for (int i = 0; i < 4; i++)
        {
            int x = t.first + dx[i], y = t.second + dy[i];
            if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1)
            {                                       // 在范围内且“第一次搜到”
                d[x][y] = d[t.first][t.second] + 1; // 距离+1
                q->push(make_pair(x, y));
            }
        }
    }
    return d[n - 1][m - 1]; // 右下角的距离
}
int main()
{
    cin >> n >> m;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            cin >> g[i][j];
        }
    }
    cout << bfs() << endl;
    return 0;
}


2.八数码

在一个 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


思路:12345678x及其剩余的状态用string 存储,这样比较的时候直接与"12345678x"比。

// 八数码
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <queue>
using namespace std;
int bfs(string start)
{
    string end = "12345678x";
    queue<string> q;              // 状态
    unordered_map<string, int> d; // 每个状态的距离
    q.push(start);
    d[start] = 0; // 起点到起点的距离为0
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
    while (q.size())
    {
        auto t = q.front(); // t此时为string
        q.pop();
        int distance = d[t];
        if (t == end)
            return d[t];
        // 状态转移
        int k = t.find("x"); // 找x的下标
        int x = k / 3, y = k % 3;
        for (int i = 0; i < 4; i++)
        {
            int a = x + dx[i], b = y + dy[i]; // 转移后x的坐标
            if (a >= 0 && a < 3 && b >= 0 && b < 3)
            {                             // 坐标未出界
                swap(t[k], t[a * 3 + b]); // 状态更新(转移x)
                if (!d.count(t))
                { // t状态之前没被搜到过
                    d[t] = distance + 1;
                    q.push(t);
                }
                /// 还原状态,为下一种转换情况做准备
                swap(t[k], t[a * 3 + b]); // 恢复状态(不要忘记!!!)
            }
        }
    }
    // 无法转换到目标状态,返回-1
    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;
}


相关文章
|
6天前
|
存储 机器学习/深度学习 算法
第十五届蓝桥杯pb组国赛E题[马与象] (15分)BFS算法 详解
第十五届蓝桥杯pb组国赛E题[马与象] (15分)BFS算法 详解
16 3
|
1天前
|
搜索推荐 算法 C++
|
1天前
|
存储 算法 Serverless
|
1天前
|
存储 算法 搜索推荐
|
8天前
|
算法 数据中心 C++
基于C++雪花算法工具类Snowflake -来自chatGPT
基于C++雪花算法工具类Snowflake -来自chatGPT
11 1
|
1天前
|
机器学习/深度学习 算法 搜索推荐
|
7天前
|
存储 算法 编译器
程序与技术分享:C++模板元编程学习笔记
程序与技术分享:C++模板元编程学习笔记
|
8天前
|
算法 搜索推荐 C++
C++之STL常用算法(遍历、查找、排序、拷贝、替换、算数生成、集合)
C++之STL常用算法(遍历、查找、排序、拷贝、替换、算数生成、集合)
14 0
|
8天前
|
存储 C++ 容器
【C++】学习笔记——map和set
【C++】学习笔记——map和set
9 0