首页 > 编程语言 >C++U5-第06课-广度优先搜索3

C++U5-第06课-广度优先搜索3

时间:2024-03-04 20:33:16浏览次数:29  
标签:fx 06 U5 单元格 C++ int 星座 dist now

温故知新

广搜的概念,编程实现基本流程

 

二进制矩阵中的最短路径]

 

 

 

 

【题意分析】
找到一个从(0,0)到达(n-1,n-1)的路径并且路径上每一个数字都为0

【思路分析】
首先如果 grid [0][0] = 1,那么显然不存在最短路径,因此输出 -1。
使用 dist[x][y] 保存左上角单元格(0,0) 到某一单元格 (x,y) 的最短路径,初始时 dist[0][0] = 1。首先,我们将单元格(0,0) 放入队列中,然后不断执行以下操作:
1.如果队列为空,那么返回 -1。
2.从队列中取出单元格 (x,y),如果该单元格等于右下角单元格,那么返回 dist [x][y]。
3.遍历该单元格的所有相邻单元格,如果相邻单元格 (x1,y1)的值为 0 且末被访问,那么令dist[x1][y1] = dist[x][y] + 1,并且将相邻单元格 (x1,y1) 放入队列中。

【参考代码】
#include <bits/stdc++.h>
using namespace std;
int n;
// 创建地图数组和标记是否用过的数组
int grid[1004][1003];
int dist[1004][1003];
// 定义方向数组和结构体储存当前位置
int dx[8] = {1, -1, 0, 0,1,1,-1,-1};
int dy[8] = {0, 0, 1, -1,1,-1,1,-1};
struct node {
    int x, y;
};
int bfs() {
    // 定义队列并将起始点压入队列,并且标记已用过
    queue<node> q;
    q.push({1, 1});
    dist[1][1] = 1;
    while (!q.empty()) {
        node now = q.front();
        q.pop();
        // 到达最终位置,输出到达最终位置的路径长度
        if (now.x == n && now.y == n) {
            return dist[now.x][now.y];
        }
        for (int i = 0; i < 8; i++) {
            int fx = dx[i] + now.x;
            int fy = dy[i] + now.y;
            // 下一个行走的位置超出边界则跳过
            if (fx < 1 || fx > n || fy < 1 || fy > n) {
                continue;
            }
            // 单元格值不为 0 或已被访问则跳过
            if (grid[fx][fy] == 1 || dist[fx][fy] <= dist[now.x][now.y] + 1) {
                continue;
            }
            // 路径长度+1并将下一个位置压入
            dist[fx][fy] = dist[now.x][now.y] + 1;
            q.push({fx, fy});
        }
    }
    // 如果不存在路径返回-1输出
    return -1;
}
int main() {
    cin >> n;
    // 将当前的图存入数组
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cin >> grid[i][j];
        }
    }
    // 如果起始位置为1,那么输出-1
    if (grid[1][1] == 1) {
        cout << "-1" << endl;
        return 0;
    }
    // 对dist数组做初始化操作
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            dist[i][j] = 9999;
        }
    }
    cout << bfs() << endl;
    return 0;
}
View Code

 

 

[【广度优先搜索(三)】观星]

 

 

 

 

 

【题意分析】
在星星图中找到星系的数量与最大星系的大小

【思路分析】
1、题目输入的是 星星 ,而不是星座

2、左边、左上、上面、右上、右边、右下、下面、左下 8 个位置的 星星为星座。

3、包含的 星星 数量相同的 星座 被视为一个 星系 (一个 星系 中的 星座 不一定相邻), 星系 的大小为 星系 中包含的所有 星星 数量。

4、问题求的是星空中有多少个 星系,这道题做法是BFS,因为文中提到了八方向。所以,我们可以利用广搜求出星座的数量以及每一个星座的面积,存入a数组。

再用桶数组存每个面积星座的数量,然后根据最大值累加星系的数量,并求出最大的面积星座,注意可以用 bb[i]∗i 计算,最后输出。

【参考代码】
#include <bits/stdc++.h>
using namespace std;
int n, m, cnt = 0;
int ans = 0;
char a[1510][1510];    // 用来存星空
int book[1510][1510];  // 用来标记那些星星我们已经找过他的星座了
int Stars[100010];     // 统计大小为i的星座有多少个
struct node {
    int x, y;  // BFS的结构体,所在第几行,第几列
} temp;
int dx[8] = {1, -1, 0, 0, 1, -1, 1, -1};
int dy[8] = {0, 0, 1, -1, 1, -1, -1, 1};
// 方向数组,往八连通扩展
int bfs(int p0, int q0) {  // 找到的这一颗星星的坐标是(p0,q0)
    queue<node> q;
    q.push({p0, q0});
    book[p0][q0] = 1;
    // 统计星座的大小
    int Size_ = 0;
    while (q.size()) {
        Size_++;  // 星座的大小加一
        temp = q.front();
        q.pop();
        for (int i = 0; i < 8; i++) {
            int fx = temp.x + dx[i];
            int fy = temp.y + dy[i];
            // 下一个位置不越界,是星星,且不重复加入队列,并标记已经访问
            if (fx >= 1 && fx <= n && fy >= 1 && fy <= m && a[fx][fy] == '*' && book[fx][fy] == 0) {
                book[fx][fy] = 1;
                q.push({fx, fy});
            }
        }
    }
    return Size_;  // 返回星座大小
}
int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> a[i][j];
        }
    }
    int w;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            // 如果是星星,并且没有找过他
            if (a[i][j] == '*' && book[i][j] == 0) {
                // 获取到星座大小,并且又多了一个大小是w的星座
                w = bfs(i, j);
                Stars[w]++;
            }
        }
    }
    for (int i = 1; i <= 100000; i++) {
        // 如果存在大小是i的星座
        if (Stars[i] != 0) {
            // 那么他们可以组成一个星系,并且更新最大星系
            cnt++;
            ans = max(ans, (i * Stars[i]));
        }
    }
    // 输出星系的数量与最大星系的大小
    cout << cnt << " " << ans << endl;
    return 0;
}
View Code

 

 

初赛知识

 

 

 作业:目前B占自己搜,或者咨询老师。

 

标签:fx,06,U5,单元格,C++,int,星座,dist,now
From: https://www.cnblogs.com/jayxuan/p/18052606

相关文章

  • 【C++】【OpenCV-4.9.0】灰度图取反(Mat属性的使用)
    此次我们将一张图像转灰度后再进行灰度取反,即黑的变白的,白的变黑的,所以我们需要获取每个像素点上的灰度级,cv中提供了一个函数at,但是这个函数还有11个重载函数,太多了,我们只用这次需要用到的,即通过读取像素点的位置来获取灰度级。◆ at() [3/12]template<typename_Tp>c......
  • 提高C++编译速度
    提高C++编译速度BuildPerformanceInsights-Crascit如何分析和提高大型项目(C/C++)的编译速度?-知乎(zhihu.com)以上链接提供了提高编译速度的方案,以及如何检查是编译哪个文件花的时间最长。实践下来,我采用的方案是直接换用ninja来替代make,结合CMake计时参数,成功将......
  • C++ 命名空间
    在C++应用程序中。例如,您可能会写一个名为xyz()的函数,在另一个可用的库中也存在一个相同的函数xyz()。这样,编译器就无法判断您所使用的是哪一个xyz()函数。因此,引入了命名空间这个概念,专门用于解决上面的问题,它可作为附加信息来区分不同库中相同名称的函数、类、变量等。......
  • C++系列:const关键字
    前言在学习C++时,const关键字的知识点分散在书的各个章节。当我们尝试在编程时使用const时,总会感觉有一些细节被遗忘,因而不能得心应手地使用const关键字。因此,本篇文章尝试着对const关键字的做一些总结。参考书籍《C++PrimerPlus》const总结这里是我做的关于const关键字的一些......
  • P1064 [NOIP2006 提高组] 金明的预算方案
    原题链接题解遍历主件,和还剩下多少钱的情况下,最多有五种购买决策1.不买2.买主件3.买主件+附件14.买主件+附件25.买主件+附件1+附件2如果当前的钱够买,那就买买看,然后加上剩下的钱能买的最大值code#include<bits/stdc++.h>usingnamespacestd;structunit{intv,......
  • (持续更新)c++结构体
    结构体指针作用:通过指针访问结构体中的成员利用操作符->可以通过结构体指针访问结构体属性 1.指针访问单一结构体#include<iostream>#include<string>#include<ctime>usingnamespacestd;structStudent{stringname;intage;intscore;};i......
  • C++ 动态内存
    C++ 动态内存C++程序中的内存分为两个部分:栈:在函数内部声明的所有变量都将占用栈内存。堆:这是程序中未使用的内存,在程序运行时可用于动态分配内存。很多时候,您无法提前预知需要多少内存来存储某个定义变量中的特定信息,所需内存的大小需要在运行时才能确定。在C++中,您可......
  • C++ 异常处理
    菜鸟教程C语言中文网程序的错误大致可以分为三种,分别是语法错误、逻辑错误和运行时错误:1)语法错误在编译和链接阶段就能发现,只有100%符合语法规则的代码才能生成可执行程序。语法错误是最容易发现、最容易定位、最容易排除的错误,程序员最不需要担心的就是这种错误。2)逻辑错......
  • 关于SAP-APP机器-R3trans -d报错-R3trans: /lib64/libstdc++.so.6: version `GLIBCXX_
    在SAP-应用-APP-机器上执行如下命令报错awpxxx03:prdadm270>R3trans-dR3trans:/lib64/libstdc++.so.6:version`GLIBCXX_3.4.26'notfound(requiredbyR3trans) 其实之前,使用过一种方法解决这个问题,可以参考笔者另一篇文章《关于Redhat-Linux中-compat-sap-c++的说......
  • Codeforces Round 806 (Div. 4) A-G(补题)
    A.YESorYES?思路:一次判断三个字母是否是y、e、s的大小写即可。这题是很久前写的,哈哈,马蜂改了不少。。#include<bits/stdc++.h>usingnamespacestd;intn;chars[5];intmain(){ scanf("%d",&n); for(inti=1;i<=n;i++){ scanf("%s",s+1); if......