P1162 填涂颜色(BFS)

题目描述

由数字 0 组成的方阵中,有一任意形状的由数字 1 构成的闭合圈。现要求把闭合圈内的所有空间都填写成 2。例如:6×6 的方阵(n=6),涂色前和涂色后的方阵如下:

如果从某个 0 出发,只向上下左右 4 个方向移动且仅经过其他 0 的情况下,无法到达方阵的边界,就认为这个 0 在闭合圈内。闭合圈不一定是环形的,可以是任意形状,但保证闭合圈内的 0 是连通的(两两之间可以相互到达)。

0 0 0 0 0 0
0 0 0 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 1 0 1
1 1 1 1 1 1
0 0 0 0 0 0
0 0 0 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 1 2 1
1 1 1 1 1 1

输入格式

每组测试数据第一行一个整数 n(1≤n≤30)。

接下来 n 行,由 0 和 1 组成的 n×n 的方阵。

方阵内只有一个闭合圈,圈内至少有一个 0。

输出格式

已经填好数字 2 的完整方阵。

输入输出样例

输入 #1复制

6
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1

输出 #1复制

0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 2 2 1
1 1 1 1 1 1

说明/提示

对于 100% 的数据,1≤n≤30。

题目链接:P1162 填涂颜色 - 洛谷

学习链接:BFS习题课(上) | 从此搞懂搜索题的套路! | 入门必看_哔哩哔哩_bilibili

代码如下: 

#include<bits/stdc++.h>
using namespace std;
int n;
int g[35][35];
bool st[35][35];//标记数组,标记矩阵上的0是否被访问过
typedef pair<int,int> PII;
queue<PII> q;
int x[4]={-1,0,1,0};
int y[4]={0,1,0,-1};

int main()
{
	cin>>n;
	
	//初始化数组,相当于给矩阵加了一圈外围0,保证数组第一个坐标永远是0 
	memset(g,0,sizeof(g));
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			cin>>g[i][j];
	
	//将第一个点入队
	q.push({0,0});
	//标记已访问过
	st[0][0]=true;
	
	//当队列不为空
	while(!q.empty())
	{
		//取出队头元素
		PII t=q.front();
		//弹出
		q.pop();
		
		//遍历它的四个方向
		for(int i=0;i<4;i++)
		{
			int nx=t.first+x[i];
			int ny=t.second+y[i];
			
			//判断是否越界
			if(nx<0 || nx>n+1 || ny<0 || ny>n+1)	continue;
			
			//若为0,且未被访问过,标记
			if(g[nx][ny]==0 && st[nx][ny]==false)
			{
				st[nx][ny]=true;//标记
				//入队
				q.push({nx,ny}); 
			} 
		} 
	} 
	
	//遍历矩阵,并将未访问过的0设置为2
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(g[i][j]==0 && st[i][j]==false)
				g[i][j]=2;
		}
	} 
	
	//输出更新后的矩阵
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
			cout<<g[i][j]<<" ";
		cout<<endl;
	}
	return 0;
} 

 

### 关于广度优先搜索 (BFS) 的洛谷题目与练习 #### BFS 基础概述 广度优先搜索(breadth-first search, 缩写为 bfs)是一种用于图的搜索算法,能够系统地展开并检查图中的所有节点以找到目标结果。该方法从初始状态出发,逐步扩展到所有的相邻节点,并按层次顺序依次处理这些节点[^1]。 以下是几类适合初学者和中级学习者的 BFS 练习题及其特点: --- #### 洛谷经典 BFS 题目推荐 1. **P1746 离开中山路** 这是一道典型的 BFS 应用题,涉及二维地图上的最短路径计算。题目要求在给定的地图上找到从起点到达终点所需的最少步数。此题考察了如何利用队列实现 BFS 层次遍历以及如何记录访问状态以避免重复计算[^2]。 ```cpp #include <bits/stdc++.h> using namespace std; int main() { // 初始化地图大小和其他参数 int n, m; cin >> n >> m; vector<string> grid(n); for(int i=0;i<n;i++) cin>>grid[i]; queue<pair<int,int>> q; // 定义队列存储坐标 bool visited[n][m]; memset(visited,false,sizeof(visited)); // 起点入队 pair<int,int> start={...}; q.push(start); visited[start.first][start.second]=true; while(!q.empty()){ auto current=q.front(); q.pop(); // 扩展当前节点的所有邻居 // ... } cout << "最小步数:" << result; } ``` 2. **P1162 填涂颜色** 此题是一个基于网格的操作问题,需要通过 BFS 来模拟填涂过程。它不仅测试了选手对于 BFS 的理解程度,还涉及到边界条件判断和多方向扩展的能力。 3. **P1378 表达式求值** 尽管表面上看这似乎不是一道标准的 BFS 问题,但实际上可以通过构建表达式的解析树并通过 BFS 对其进行层序遍历来解决。这类题目有助于加深对 BFS 数据结构的理解。 4. **P1984 地牢大师** 描述了一个三维空间内的迷宫逃脱场景,增加了维度之后使得问题更加复杂化但也更贴近实际应用场景。解答过程中需特别留意内存优化技巧以免超限。 5. **P1555 方格取数 II** 结合动态规划思想的一道综合性较强的大规模数据处理挑战赛项目。虽然主要依赖DP完成最终得分统计工作,但在预处理阶段依然需要用到高效的BFS策略快速定位可达区域范围。 --- #### 注意事项 当尝试上述任何一类竞赛型编程任务时,请务必牢记以下几点建议: - 明确输入输出格式; - 准备好必要的辅助工具函数比如读取矩阵或者打印调试信息等操作; - 合理设置时间/空间限制下的性能指标评估方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值