题解:学而思编程 重新涂色
本文分享的必刷题目是从蓝桥云课、洛谷、AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。
欢迎大家订阅我的专栏:算法题解:C++与Python实现!
附上汇总贴:算法竞赛备考冲刺必刷题(C++) | 汇总
【题目来源】
学而思编程:重新涂色
【题目描述】
有一个 \(H\) 行 \(W\) 列的方格棋盘,从上数第 \(i\) 行,从左数第 \(j\) 列的格子记为 \((i,j)\)。小猴从 \((1,1)\) 出发,每次可以走到上下左右的相邻格子,目标是走到 \((H,W)\)。方格被涂成了黑色和白色,小猴只能进入白色的格子,不能进入黑色格子。
在游戏开始前,小猴可以将任意多个白色格子涂黑,但是不能涂黑起点 \((1,1)\) 和终点 \((H,W)\)。涂色必须在游戏开始前完成,开始游戏后就不能涂黑格子了。
到达终点后,小猴能得到的分数等于游戏开始前涂黑的格子的数量,给出初始的棋盘状态,求出小猴能得到的最高分数。如果无法到达终点,输出 \(-1\)。
【输入】
第一行,\(2\) 个正整数 \(H,W\),表示棋盘行数和列数
接下来 \(H\) 行,每行 \(W\) 个字符,给出棋盘初始状态,'#'表示黑格,'.'表示白格
【输出】
输出小猴能得到的最高分数,若无法到达终点,输出 \(-1\)。
【输入样例】
3 3
..#
#..
...
【输出样例】
2
【解题思路】

【算法标签】
BFS-二维
【代码详解】
#include <bits/stdc++.h>
using namespace std;
const int N = 55;
int n, m, cnt;
char g[N][N]; // 地图
int dist[N][N]; // 存储从起点到每个位置的最短距离
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
struct Node
{
int x, y;
};
queue<Node> q;
// 广度优先搜索,计算从起点(1,1)到所有可到达位置的最短距离
void bfs()
{
q.push((Node){1, 1});
memset(dist, -1, sizeof(dist));
dist[1][1] = 0;
while (!q.empty())
{
int x = q.front().x, y = q.front().y;
q.pop();
for (int i = 0; i < 4; i++)
{
int nx = x + dx[i], ny = y + dy[i];
// 检查边界
if (nx < 1 || nx > n || ny < 1 || ny > m)
{
continue;
}
// 检查是否是障碍物
if (g[nx][ny] == '#')
{
continue;
}
// 检查是否已访问
if (dist[nx][ny] != -1)
{
continue;
}
dist[nx][ny] = dist[x][y] + 1;
q.push((Node){nx, ny});
}
}
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> g[i][j];
// 统计空地数量
if (g[i][j] == '.')
{
cnt++;
}
}
}
bfs();
// 如果无法到达终点
if (dist[n][m] == -1)
{
cout << -1 << endl;
}
else
{
// 输出结果:总空地数 - 最短路径经过的格子数
// dist[n][m]是从起点到终点的步数,+1是因为包括起点
cout << cnt - (dist[n][m] + 1) << endl;
}
return 0;
}
【运行结果】
3 3
..#
#..
...
2
浙公网安备 33010602011771号