首页 > 编程语言 >C++U5-05-广度优先搜索2

C++U5-05-广度优先搜索2

时间:2023-11-14 11:55:21浏览次数:33  
标签:05 U5 位置 C++ int maxn && push 步数

广搜逻辑

 

 广搜代码核心思路

 广搜伪代码

前面讲解的广度优先搜索案例都类似迷宫类的问题,但有些非迷宫类问题也可以使用广搜的思路解决

[【广搜2】填涂颜色]

【算法分析】
可以在外面增加一圈 0,然后从 (0,0) 位置开始广搜所有为 0 的位置,没有被搜索到且为 0 的位置就应该变为 2。

【参考代码】
#include<bits/stdc++.h>
using namespace std;

int a[39][39];
bool vis[39][39];
struct node {
    int x, y;
}l,r;
int n;
int dir[4][2] = { -1,0,0,1,1,0,0,-1 };
void bfs(int x, int y) {
    queue<node> q;
    q.push({ x,y });
    vis[x][y] = 1;
    while (q.size()) {
        r = q.front();
        q.pop();
        for (int i = 0; i < 4; i++) {
            l.x = r.x + dir[i][0], l.y = r.y + dir[i][1];
            if (l.x >= 0 && l.x <= n + 1 && l.y >= 0 && l.y <= n + 1 && !vis[l.x][l.y] && a[l.x][l.y] == 0) {
                vis[l.x][l.y] = 1;
                q.push(l);
            }
        }
    }
}
int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cin >> a[i][j];
        }
    }
    bfs(0, 0);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (a[i][j] == 0 && !vis[i][j]) {
                cout << 2 << " ";
            }
            else cout << a[i][j] << " ";
        }
        cout << '\n';
    }
    return 0;
}
View Code

[【广搜2】抓住那头牛]

 

【算法分析】
由于位置的个数很少且要求最小步数,可以考虑从 n 位置开始广搜,同时用一个数组 d,d 
i
​
  表示从 n 位置到 i 位置需要的步数,最后输出 d 
k
​
  即可。

【参考代码】
#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e5 + 9;
int d[maxn];
int main() {
    int n, k;
    cin >> n >> k;
    memset(d, -1, sizeof(d));
    d[n] = 0;
    queue<int> q;
    q.push(n);
    while (q.size()) {
        int r = q.front();
        q.pop();
        if (r >= 1 && d[r - 1] == -1) {
            d[r - 1] = d[r] + 1;
            q.push(r - 1);
        }
        if (r < 1e5 && d[r + 1] == -1) {
            d[r + 1] = d[r] + 1;
            q.push(r + 1);
        }
        if (2 * r <= 1e5 && d[2 * r] == -1) {
            d[2 * r] = d[r] + 1;
            q.push(2 * r);
        }
    }
    cout << d[k];
    return 0;
}
View Code

 

[【广搜2】奇怪的电梯]

【算法分析】
由于位置的个数很少且要求最小步数,可以考虑从 A 位置开始广搜,同时用一个数组 d,di 表示从 A 位置到 i 位置需要的步数,最后输出 d B
​
  即可。

【参考代码】
#include<bits/stdc++.h>
using namespace std;

const int maxn = 2e2 + 9;
int d[maxn], k[maxn];
int main() {
    int N, A, B;
    cin >> N >> A >> B;
    for (int i = 1; i <= N; i++) cin >> k[i];
    memset(d, -1, sizeof(d));
    d[A] = 0;
    queue<int> q;
    q.push(A);
    while (q.size()) {
        int r = q.front();
        q.pop();
        if (r + k[r] <= N && d[r + k[r]] == -1) {
            d[r + k[r]] = d[r] + 1;
            q.push(r + k[r]);
        }
        if (r - k[r] >= 1 && d[r - k[r]] == -1) {
            d[r - k[r]] = d[r] + 1;
            q.push(r - k[r]);
        }
    }
    cout << d[B];
    return 0;
}
View Code

 

[【广搜2】倒水问题]

 

【算法分析】
可以从 (0,0) 状态开始广搜,在广搜的每一步记录 x,y,step,s,分别表示第一个杯子装的水,第二个杯子装的水,达到这个状态需要的步数,达到这个状态的操作步骤。

【参考代码】
#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e2 + 9;
bool vis[maxn][maxn];
struct node {
    int x, y, step;
    string s;
}l, r;
int main() {
    int n, m, k;
    cin >> n >> m >> k;
    vis[0][0] = 1;
    queue<node> q;
    q.push({ 0,0,0,"" });
    while (q.size()) {
        r = q.front();
        q.pop();
        if (r.x == k || r.y == k) {
            cout << r.step << '\n' << r.s;
            return 0;
        }
        l.x = n, l.y = r.y, l.step = r.step + 1, l.s = r.s + "FILL(1)\n";
        if (!vis[l.x][l.y]) {
            vis[l.x][l.y] = 1;
            q.push(l);
        }
        l.x = r.x, l.y = m, l.step = r.step + 1, l.s = r.s + "FILL(2)\n";
        if (!vis[l.x][l.y]) {
            vis[l.x][l.y] = 1;
            q.push(l);
        }
        l.x = 0, l.y = r.y, l.step = r.step + 1, l.s = r.s + "DROP(1)\n";
        if (!vis[l.x][l.y]) {
            vis[l.x][l.y] = 1;
            q.push(l);
        }
        l.x = r.x, l.y = 0, l.step = r.step + 1, l.s = r.s + "DROP(2)\n";
        if (!vis[l.x][l.y]) {
            vis[l.x][l.y] = 1;
            q.push(l);
        }
        l.x = max(0, r.x + r.y - m), l.y = min(m, r.x + r.y), l.step = r.step + 1, l.s = r.s + "POUR(1,2)\n";
        if (!vis[l.x][l.y]) {
            vis[l.x][l.y] = 1;
            q.push(l);
        }
        l.x = min(n, r.x + r.y), l.y = max(0, r.x + r.y - n), l.step = r.step + 1, l.s = r.s + "POUR(2,1)\n";
        if (!vis[l.x][l.y]) {
            vis[l.x][l.y] = 1;
            q.push(l);
        }
    }
    cout << "impossible";
    return 0;
}
View Code

 

标签:05,U5,位置,C++,int,maxn,&&,push,步数
From: https://www.cnblogs.com/jayxuan/p/17831294.html

相关文章

  • 单例模式C++实现
    单例模式全局静态变量实现饿汉式单例模式饿汉式实现方式是线程安全的。黑#includeusingnamespacestd;/*饿汉式单例模式*/classSingleObject{private:staticSingleObjectinstance;SingleObject(){std::cout<<"Singleton......
  • C++模拟键盘操作
    前言:C++/C语言模拟键盘操作十分的黑科技啊,作者也是借鉴了C/C++模拟键盘操作(一)_折竹丶的博客-CSDN博客_c++模拟键盘​​​​​​​​​​​​​​  来做一个小小的全面总结,有兴趣可以去看原创 键盘操作:在C++中有一个头文件:windows.h我们可以尝试导入他: #include<......
  • C++ Primer学习笔记——第十一章
    第十一章关联容器前言关联容器和顺序容器有着本质的不同:关联容器中的元素是按关键字来保存和访问的。与之相对,顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的。(MySQL中元素就是按照关联容器进行保存)关联容器支持高效的关键字查找和访问。两个主要的关联容器(assoc......
  • C++多态
    1、静态多态(1)函数重载 函数重载以参数的类型或数量不同来区分不同用途的同名函数。不以返回值不同来区分函数。编译器在调用函数时会在意函数的参数,不会在意函数的返回值。intmyAdd(inta,intb);floatmyAdd(doublea,doubleb);(2)运算符重载 使用关键字operator来......
  • SPOJ1805 HISTOGRA - Largest Rectangle in a Histogram 题解
    LinkSPOJ1805HISTOGRA-LargestRectangleinaHistogramQuestion在一条水平线上有\(n\)个高为\(a_i\)的矩形,求包含于这些矩形的最大子矩形面积。Solution我们定义\(L_i\)表示有\(a_i\)这个高度的一根悬线,往左最多能平移到什么位置初始化显然,\(a_i=i\)考虑转移......
  • C/C++知识补充
    运算符算术运算符关系运算符逻辑运算符位运算符赋值运算符杂项运算符运算符描述实例+把两个操作数相加A+B将得到30-从第一个操作数中减去第二个操作数A-B将得到-10*把两个操作数相乘A*B将得到200/分子除以分母B/A将得到......
  • Linux Ubuntu部署C++环境与VS Code编辑器
      本文介绍在LinuxUbuntu操作系统下,配置VisualStudioCode软件与C++代码开发环境的方法。  在文章VMware虚拟机中安装LinuxUbuntu操作系统中,我们介绍了LinuxUbuntu操作系统的下载、安装方法;本文则基于前述基础,继续介绍在LinuxUbuntu操作系统中配置VisualStudioCode软......
  • C++ 字符串类 string
    @TOC前言在C++中,字符串是一种常见的数据类型,用于存储和操作文本数据。C++标准库中提供了std::string类,它是一个功能强大的字符串类,提供了丰富的方法和操作符,使我们能够轻松地处理字符串。一、string类型概括std::string是C++标准库中定义的字符串类,它在<string>头文件中声明。它......
  • 【C++】【图像处理】均值滤波和高斯滤波(低通滤波)算法解析(以.raw格式的图像为基础进行
    1voidmeanFilter(BYTE*image,intwidth,intheight,BYTE*outImg)2{3//均值滤波4intsmth[9];5inti,j,m,n;6BYTEblock[9];78//高斯卷积核初始化9smth[0]=1,smth[1]=2,smth[2]=1,10smth[3]=2,......
  • C++界面库(十几种,很全)
    C++界面库是用于GUI界面设计的工具包,可以帮助开发人员快速开发出美观、易用的界面。在选择C++界面库的时候,开发人员需要根据项目要求、使用场景、开发难易程度以及所适配的操作系统等因素进行综合考虑。 下面列举了十几种常见的C++界面库,简单介绍它们的安装、使用、特点和适用......