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

C++题解:【入门】快乐的马里奥(BFS)

描述

马里奥是一个快乐的油漆工人,这天他接到了一个油漆任务,要求马里奥把一个 n 行 m 列的矩阵每一格都用油漆标记一个数字,标记的顺序按照广度优先搜索的方式进行,也就是他会按照如下方式标记:
1 、首先标记第 1 行第 1 列的单元格,标记数字为 1 ;
2 、然后标记当前单元格上下左右四个方向所有能标记的单元格,且:
① 标记顺序按照:右、下、左、上的优先级;
② 不能标记到矩阵外,且标记过的数字不能重复标记;
3 、当本单元格标记结束,寻找比本单元格中数字大 1 的单元格,标记那个单元格的上下左右四个方向,也是按照步骤 2 所示的要求进行标记。
依次类推,直到所有单元格都被标记。
比如:如果有一个3 * 3 的矩阵如下,那么首先标记 1,1 单元格,并按照上面步骤 2 的要求标记其四周能够标记的单元格,标记结果如下:
 


接下来,标记比 1,1 格大 1 的数字的四周的单元格,也就是标记值为 2 的单元格四周的单元格,标记结果如下:
 


接下来标记值为 3 的单元格四周的单元格,标记结果如下:
 


接下来标记值为 4 的单元格四周的单元格,标记结果如下:
 


接下来标记值为 5 的单元格四周的单元格,标记结果如下:
 


接下来标记值为 6 的单元格四周的单元格,但这个数字四周的单元格已经被标记,因此继续标记值为7四周的单元格,标记结果如下:
 


此时,发现标记结束,得到如上图所示的标记结果。

输入描述

两个整数 n 和 m , n 和 m 都是 3~100 之间的整数。

输出描述

输出 n 行 m 列的标记后的矩阵,输出每个数后空一格。

用例输入 1 

3 3

用例输出 1 

1 2 4
3 5 7
6 8 9

来源

广搜

AC CODE

#include<bits/stdc++.h>
using namespace std;int a[110][110],q[10100][3];int fx[5]={0,0,1,0,-1};
int fy[5]={0,1,0,-1,0};
int tx,ty;
int k=1;
int n,m,i,j;int head=1,tail=1;int main()
{cin>>n>>m;a[1][1]=k;k++;q[1][1]=1;q[1][2]=1;while(head<=tail){for(i=1;i<=4;i++){tx=q[head][1]+fx[i];ty=q[head][2]+fy[i];if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&a[tx][ty]==0){tail++;q[tail][1]=tx;q[tail][2]=ty;a[tx][ty]=k;k++;}} head++; } for(i=1;i<=n;i++){for(j=1;j<=m;j++){cout<<a[i][j]<<" ";}cout<<endl;} return 0;} 

题目详解

一、问题核心理解

这道题要求我们使用广度优先搜索(BFS)对n×m矩阵进行数字标记,核心规则是:

• 从(1,1)位置开始标记为1

• 按"右、下、左、上"的优先级顺序标记相邻未访问格子

• 每次处理完当前层级,按数字递增顺序处理下一层级

二、代码整体架构

代码采用经典BFS实现,主要包含:

• 矩阵存储结构 a[110][110]

• 队列结构 q[10100][3] 用于BFS遍历

• 方向数组 fx[] 和 fy[] 定义搜索顺序

三、关键代码详解

1. 方向数组设计

int fx[5]={0,0,1,0,-1};  // x方向偏移量
int fy[5]={0,1,0,-1,0};  // y方向偏移量


• 索引1-4对应"右、下、左、上"四个方向

• 偏移量设计:

◦ 右:(0,1) 列+1

◦ 下:(1,0) 行+1

◦ 左:(0,-1) 列-1

◦ 上:(-1,0) 行-1

2. 初始化操作

cin>>n>>m;
a[1][1]=k;  // 起点(1,1)标记为1
k++;        // 下一个标记值准备q[1][1]=1;  // 起点入队
q[1][2]=1;


• 矩阵下标从1开始,符合题目习惯

• 队列初始存入起点坐标(1,1)

3. BFS核心逻辑

while(head<=tail)  // 队列非空时循环
{for(i=1;i<=4;i++)  // 按优先级遍历四个方向{tx=q[head][1]+fx[i];  // 计算新坐标ty=q[head][2]+fy[i];// 检查坐标合法性和是否已标记if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&a[tx][ty]==0){tail++;                  // 队列尾指针后移q[tail][1]=tx;           // 新坐标入队q[tail][2]=ty;a[tx][ty]=k;             // 标记当前格子k++;                     // 标记值递增}}head++;  // 处理完当前节点,队头指针后移
}


• 队列采用"头进头出"的BFS标准模式

• 每个节点出队时,按优先级检查四个方向

• 合法新节点入队并标记,保证按层次遍历

4. 结果输出

for(i=1;i<=n;i++)
{for(j=1;j<=m;j++){cout<<a[i][j]<<" ";}cout<<endl;
}


• 按行优先顺序输出矩阵

• 每个数字后加空格,符合题目格式要求

四、算法执行过程分析

以3×3矩阵为例:

1. 初始队列:[(1,1)],标记a[1][1]=1

2. 处理队头(1,1),按顺序检查四个方向:

◦ 右(1,2)合法,标记为2并入队

◦ 下(2,1)合法,标记为3并入队

◦ 左(1,0)越界,跳过

◦ 上(0,1)越界,跳过
此时队列:[(1,2),(2,1)]

3. 处理队头(1,2),检查方向:

◦ 右(1,3)合法,标记为4并入队

◦ 下(2,2)合法,标记为5并入队

◦ 左(1,1)已标记,跳过

◦ 上(0,2)越界,跳过
队列更新:[(2,1),(1,3),(2,2)]

4. 以此类推,最终得到题目要求的标记结果

五、算法复杂度分析

• 时间复杂度:O(n×m),每个格子最多入队一次

• 空间复杂度:O(n×m),队列和矩阵存储需求

• 优化点:队列大小设为10100,足够容纳100×100矩阵的所有格子

六、总结

该代码通过标准BFS实现了题目要求的矩阵标记逻辑,核心在于:

1. 方向数组的优先级顺序设计

2. 队列的正确入队出队操作

3. 矩阵边界和已标记状态的检查

这种BFS遍历方式保证了每个格子按层次顺序被标记,完美符合题目要求的"广度优先搜索"规则。

相关文章:

  • 从代码学习深度学习 - 预训练BERT PyTorch版
  • 【LeetCode 热题 100】15. 三数之和——排序 + 双指针解法
  • FastAPI框架的10个重要知识点总结
  • Chromium 136 编译指南 macOS篇:编译流程(五)
  • Linux进程间通信——信号
  • kibana和elasticsearch安装
  • (详细介绍)线性代数中的零空间(Null Space)
  • Git 使用手册:从入门到精通
  • MCPServer编程与CLINE配置调用MCP
  • ubuntu20.04速腾聚创airy驱动调试
  • Redis哨兵模式的学习(三)
  • 百度萝卜快跑携4颗禾赛激光雷达进军迪拜,千辆L4无人车开启全球化战略
  • Tensor的常用计算方法(torch示例说明)
  • RPC - 客户端注册和发现模块
  • Unity Addressable使用之AddressableAssetSettings
  • Java UDP Socket 实时在线刷卡扫码POS消费机服务端示例源码
  • 【全开源】填表问卷统计预约打卡表单系统+uniapp前端
  • 亚马逊认证考试系列 - 第一部份:基础服务 - AWS SAA C03
  • GPT-1 与 BERT 架构
  • Duende Identity Server学习之一:认证服务器及一个Oidc/OAuth认证、用于Machine 2 Machine的客户端
  • 合肥瑶海区/沈阳seo收费
  • 网址注册了怎么做网站/互联网广告营销是什么
  • 做100个网站效果/如何注册网站怎么注册
  • 可信赖的广州做网站/沈阳seo按天计费
  • 智慧团建网站怎么转团关系/全网关键词搜索排行
  • 丽水做企业网站的地方/潍坊百度网站排名