题解:学而思编程 重新涂色

本文分享的必刷题目是从蓝桥云课洛谷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
posted @ 2026-06-24 18:10  团爸讲算法  阅读(6)  评论(0)    收藏  举报