当前位置: 首页 > wzjs >正文

网站优化关键词排名公司网站建设报价单模板

网站优化关键词排名公司,网站建设报价单模板,高中数学 wordpress,btb电商平台在算法竞赛中,方格图(Grid)是常见的问题场景(如迷宫、岛屿问题等)。DFS常用于遍历方格中的连通区域,判断连通性。 一、方格图的DFS核心思想 图的表示 方格图通常用二维数组表示,每个格子…

        在算法竞赛中,方格图(Grid)是常见的问题场景(如迷宫、岛屿问题等)。DFS常用于遍历方格中的连通区域,判断连通性。


一、方格图的DFS核心思想

  1. 图的表示
            方格图通常用二维数组表示,每个格子可能有不同的状态(例如可通行或不可通行)。例如:

    • grid[i][j] = 0 表示水域(不可通行)

    • grid[i][j] = 1 表示陆地(可通行)

  2. 移动方向
    根据题目要求,每个格子可以向 4方向(上下左右)或 8方向(包括对角线)移动。需要定义方向数组:

    // 4方向:上、右、下、左
    int dx4[] = {-1, 0, 1, 0};
    int dy4[] = {0, 1, 0, -1};// 8方向:包括对角线
    int dx8[] = {-1, -1, 0, 1, 1, 1, 0, -1};
    int dy8[] = {0, 1, 1, 1, 0, -1, -1, -1};
  3. DFS遍历步骤

    • 从起点出发,标记当前格子为已访问。

    • 遍历所有允许的方向,检查下一个格子是否在边界内、未被访问且可通行。

    • 递归访问所有连通区域。


二、C++代码实现

场景示例:统计方格图中的连通区域数量(如岛屿数量)

#include <iostream>
#include <vector>
using namespace std;// 4方向移动数组
const int dx4[] = {-1, 0, 1, 0};
const int dy4[] = {0, 1, 0, -1};// 8方向移动数组
const int dx8[] = {-1, -1, 0, 1, 1, 1, 0, -1};
const int dy8[] = {0, 1, 1, 1, 0, -1, -1, -1};// DFS遍历函数(4方向)
void dfs(vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y) {int rows = grid.size();int cols = grid[0].size();visited[x][y] = true; // 标记当前格子已访问// 遍历4个方向for (int i = 0; i < 4; i++) {int nx = x + dx4[i];int ny = y + dy4[i];// 检查边界、是否可访问、是否已访问if (nx >= 0 && nx < rows && ny >= 0 && ny < cols && grid[nx][ny] == 1 && !visited[nx][ny]) {dfs(grid, visited, nx, ny);}}
}// 统计连通区域数量
int countConnectedRegions(vector<vector<int>>& grid) {if (grid.empty()) return 0;int rows = grid.size();int cols = grid[0].size();vector<vector<bool>> visited(rows, vector<bool>(cols, false));int count = 0;for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {// 发现未访问的陆地,启动DFS并计数if (grid[i][j] == 1 && !visited[i][j]) {dfs(grid, visited, i, j);count++;}}}return count;
}int main() {// 示例输入:5x5的方格图vector<vector<int>> grid = {{1, 1, 0, 0, 0},{1, 1, 0, 0, 0},{0, 0, 1, 0, 0},{0, 0, 0, 1, 1}};cout << "连通区域数量(4方向): " << countConnectedRegions(grid) << endl;return 0;
}

三、代码解析

  1. 方向数组

    • dx4 和 dy4 表示4个方向的坐标变化。

    • dx8 和 dy8 表示8个方向的坐标变化(可用于更复杂的连通性判断)。

  2. DFS函数

    • 递归访问当前格子的所有相邻可行走格子。

    • 通过 visited 数组避免重复访问。

  3. 统计连通区域

    • 遍历所有格子,对每个未访问的陆地启动一次DFS,统计启动次数即为连通区域数量。


四、扩展:8方向连通性

若允许8方向移动,只需修改方向数组和遍历循环:

// 修改DFS中的方向遍历
for (int i = 0; i < 8; i++) {int nx = x + dx8[i];int ny = y + dy8[i];// ... 其他逻辑不变
}

五、复杂度分析

  • 时间复杂度O(rows × cols),每个格子被访问一次。

  • 空间复杂度O(rows × cols),用于存储 visited 数组。


六、应用场景

  1. 岛屿问题(LeetCode 200)

  2. 迷宫寻路

  3. 图像中的连通区域分析

通过调整方向数组和状态判断逻辑,DFS可灵活应对各类方格图连通性问题。


七、 例题解析

1、最大连通 - 蓝桥云课

问题描述

小蓝有一个 30 行 60 列的数字矩阵,矩阵中的每个数都是 0 或 1 。


110010000011111110101001001001101010111011011011101001111110010000000001010001101100000010010110001111100010101100011110 001011101000100011111111111010000010010101010111001000010100 101100001101011101101011011001000110111111010000000110110000 010101100100010000111000100111100110001110111101010011001011 010011011010011110111101111001001001010111110001101000100011 101001011000110100001101011000000110110110100100110111101011 101111000000101000111001100010110000100110001001000101011001 001110111010001011110000001111100001010101001110011010101110 001010101000110001011111001010111111100110000011011111101010 011111100011001110100101001011110011000101011000100111001011 011010001101011110011011111010111110010100101000110111010110 001110000111100100101110001011101010001100010111110111011011 111100001000001100010110101100111001001111100100110000001101 001110010000000111011110000011000010101000111000000110101101 100100011101011111001101001010011111110010111101000010000111 110010100110101100001101111101010011000110101100000110001010 110101101100001110000100010001001010100010110100100001000011 100100000100001101010101001101000101101000000101111110001010 101101011010101000111110110000110100000010011111111100110010 101111000100000100011000010001011111001010010001010110001010 001010001110101010000100010011101001010101101101010111100101 001111110000101100010111111100000100101010000001011101100001 101011110010000010010110000100001010011111100011011000110010 011110010100011101100101111101000001011100001011010001110011 000101000101000010010010110111000010101111001101100110011100 100011100110011111000110011001111100001110110111001001000111 111011000110001000110111011001011110010010010110101000011111 011110011110110110011011001011010000100100101010110000010011 010011110011100101010101111010001001001111101111101110011101

如果从一个标为 1 的位置可以通过上下左右走到另一个标为 1 的位置,则称两个位置连通。与某一个标为 1 的位置连通的所有位置(包括自己)组成一个连通分块。

请问矩阵中最大的连通分块有多大?

答案提交

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

算法代码: 

# include <bits/stdc++.h>  // 包含标准库的所有头文件
using namespace std;  // 使用标准命名空间// int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; // 定义四个方向的移动:上、右、下、左
// char g[100][100];  // 定义一个100x100的字符数组,用于存储矩阵
// int n = 30, m = 60;  // 定义矩阵的行数n为30,列数m为60// int dfs(int x, int y) {  // 定义深度优先搜索函数,参数为当前坐标[x, y]
//     if (g[x][y] == '0') return 0;  // 如果当前点是'0',返回0,表示不连通
//     g[x][y] = '0';  // 将当前点从'1'改为'0',标记为已访问
//     int ans = 1;  // 初始化连通块的大小为1
//     for (int i = 0; i < 4; i++) {  // 遍历当前点的四个邻居
//         int nx = x + dx[i], ny = y + dy[i];  // 计算邻居的坐标
//         if (nx < 0 || ny < 0 || nx >= n || ny >= m)  // 如果邻居坐标超出边界
//             continue;  // 跳过该邻居
//         ans += dfs(nx, ny);  // 递归调用dfs,累加连通块的大小
//     }
//     return ans;  // 返回当前连通块的大小
// }// int main() {
//     for (int i = 0; i < n; i++) cin >> g[i];  // 输入矩阵的每一行
//     int ans = 0;  // 初始化最大连通块的大小为0
//     for (int i = 0; i < n; i++)  // 遍历矩阵的每一行
//         for (int j = 0; j < m; j++)  // 遍历矩阵的每一列
//             if (g[i][j] == '1')  // 如果当前点是'1'
//                 ans = max(ans, dfs(i, j));  // 更新最大连通块的大小
//     cout << ans;  // 输出最大连通块的大小
//     return 0;  // 程序正常结束
// }int main()
{cout<<"148";return 0;
}

        先执行上面注释中的代码,输入测试数据(注意删除测试数据中间的空行),得到的答案后直接提交答案。因为测试数据挺多挺大的,使用DFS会超时是正常的,因为DFS使用到了递归(会占用到很大的栈空间,超过系统栈空间,会导致栈溢出),但是这是个填空题,直接搞出答案就可以了。

2、P1868 - 连接草坪(II) - New Online Judge 

算法代码: 

#include <bits/stdc++.h>  // 包含标准库的所有头文件
using namespace std;  // 使用标准命名空间int n, m;  // 定义矩阵的行数n和列数m
char Map[55][55];  // 定义一个55x55的字符数组,用于存储地图
int id[55][55], id_cnt = 0;  // id[x][y]表示点(x,y)属于第id_cnt个草地,id_cnt从1开始计数
vector<pair<int, int>> A[4];  // A[i]存储第i个草地中的所有点int dir[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};  // 定义四个方向的移动:下、右、上、左void dfs(int x, int y, int c) {  // 深度优先搜索函数,参数为当前坐标[x, y]和草地编号cid[x][y] = c;  // 标记点(x,y)属于第c个草地A[c].push_back(make_pair(x, y));  // 将点(x,y)加入第c个草地的点集中for (int i = 0; i < 4; i++) {  // 遍历当前点的四个邻居int nx = x + dir[i][0], ny = y + dir[i][1];  // 计算邻居的坐标if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;  // 如果邻居坐标超出边界,跳过if (Map[nx][ny] == '.') continue;  // 如果邻居是土地,跳过if (id[nx][ny]) continue;  // 如果邻居已经遍历过,跳过dfs(nx, ny, c);  // 递归调用dfs,继续搜索}
}int Count(int x, int y, int i) {  // 计算点(x,y)到第i个草地的最短距离int ans = 100;  // 初始化最短距离为一个较大的值for (auto a : A[i])  // 遍历第i个草地的所有点ans = min(ans, abs(a.first - x) + abs(a.second - y));  // 计算曼哈顿距离并更新最小值return ans;  // 返回最短距离
}int main() {cin >> n >> m;  // 输入矩阵的行数n和列数mfor (int i = 0; i < n; i++) cin >> Map[i];  // 输入地图的每一行// 第1步:标记每个点属于哪个连通块for (int i = 0; i < n; i++)for (int j = 0; j < m; j++)if (Map[i][j] == 'X' && !id[i][j])  // 如果当前点是草地且未被标记dfs(i, j, ++id_cnt);  // 进行DFS,标记连通块int ans = 100;  // 初始化答案为较大的值// 第2步:枚举每块土地,计算它到3个草地的最短距离for (int i = 0; i < n; i++)for (int j = 0; j < m; j++)if (Map[i][j] == '.')  // 如果当前点是土地ans = min(ans, Count(i, j, 1) + Count(i, j, 2) + Count(i, j, 3) - 2);  // 计算到三个草地的最短距离并更新答案// 第3步:计算3个草地之间的最短距离int Min[4] = {0, 100, 100, 100};  // 初始化草地之间的最短距离for (int i = 1; i <= 3; i++) {  // 遍历每个草地int j = i + 1 <= 3 ? i + 1 : 1;  // 计算下一个草地的编号for (auto a : A[i])  // 遍历第i个草地的所有点Min[j] = min(Min[j], Count(a.first, a.second, j));  // 计算到下一个草地的最短距离并更新}// 第4步:计算连通3个草地的最短距离,并与情况(1)的结果比较for (int i = 1; i <= 3; i++)ans = min(ans, Min[i] + Min[i + 1 <= 3 ? i + 1 : 1] - 2);  // 计算连通三个草地的最短距离并更新答案cout << ans << endl;  // 输出最终答案return 0;  // 程序正常结束
}

http://www.dtcms.com/wzjs/507806.html

相关文章:

  • 手机网站方案编写百度流量
  • 个人网站备案网址seo咨询邵阳
  • wordpress全站301鹤壁seo推广
  • 北京网站建设的价格口碑营销的优势有哪些
  • 刷赞网站建设深圳网站建设开发公司
  • wordpress 二级导航制作网站优化公司收费
  • 外贸网站wordpress加sslseo海外
  • 长沙市网站建设seo优化网站推广
  • 做关键词排名卖网站百度云网盘免费资源
  • 建一个外贸网站要多少钱泉州网站建设优化
  • 昆明学校网站设计公司怎么自己弄一个网站
  • 网站建设独立优化技术
  • 重庆的平台公司山东自助seo建站
  • 我要自学网首页网站建设百度的链接
  • 做网站一定要后台嘛国际新闻界官网
  • 网站建设图片手机免费入驻的卖货平台有哪些
  • 海安网站开发seo优化有哪些
  • 正规的彩票网站怎么做百度推广登录入口下载
  • 手机怎么查看网站代码实现的南宁seo外包服务商
  • 北京微网站app镇江seo
  • 济南信息化网站百度公司高管排名
  • 招商加盟网站的图应该怎么做软文
  • 旅游景点网站模板大全网站网络营销公司
  • 去泰国做赌博发网站百度网页广告怎么做
  • 哪里有免费的网站域名网站优化排名
  • 西宁做网站的公司旭云网络企业管理培训免费课程
  • 哈尔滨网站建设设计公司郑州网站seo外包公司
  • 河南网站制作济南网站优化排名推广
  • seo优化性网站建设病毒式营销
  • 网站开发作业代做适合seo优化的网站