GESP认证C++编程真题解析 | B4263 [GESP202503 四级] 荒地开垦

​欢迎大家订阅我的专栏:算法题解:C++与Python实现!
本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战!

专栏特色
1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰的代码实现与详细指导,帮助您夯实算法基础。
2.系统化学习路径:按照算法类别和难度分级,从基础到进阶,循序渐进,帮助您全面提升编程能力与算法思维。

适合人群:

  • 准备参加蓝桥杯、GESP、CSP-J、CSP-S等信息学竞赛的学生
  • 希望系统学习C++/Python编程的初学者
  • 想要提升算法与编程能力的编程爱好者

附上汇总帖:GESP认证C++编程真题解析 | 汇总


【题目来源】

洛谷:B4263 [GESP202503 四级] 荒地开垦 - 洛谷

【题目描述】

小杨有一大片荒地,可以表示为一个 n n n m m m 列的网格图。

小杨想要开垦这块荒地,但荒地中一些位置存在杂物,对于一块不存在杂物的荒地,该荒地可以开垦当且仅当其上下左右四个方向相邻的格子均不存在杂物。

小杨可以选择至多一个位置,清除该位置的杂物,移除杂物后该位置变为荒地。小杨想知道在清除至多一个位置的杂物的情况下,最多能够开垦多少块荒地。

【输入】

第一行包含两个正整数 n , m n,m n,m,含义如题面所示。

之后 n n n 行,每行包含一个长度为 m m m 且仅包含字符 .# 的字符串。如果为 .,代表该位置为荒地;如果为 #,代表该位置为杂物。

【输出】

输出一个整数,代表在清除至多一个位置的杂物的情况下,最多能够开垦的荒地块数。

【输入样例】

3 5
.....
.#..#
.....

【输出样例】

11

【算法标签】

《洛谷 B4263 荒地开垦》 #模拟# #枚举# #GESP# #2025#

【代码详解】

#include 
using namespace std;

// 定义常量N为地图最大尺寸
const int N = 1005;

// 定义变量:n行数,m列数,ans初始答案
int n, m, ans;
// 定义二维数组存储地图,1表示障碍物,0表示空地
int a[N][N];
// 定义四个方向的偏移量:上、右、下、左
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

// 检查(x,y)位置四周是否有障碍物
bool check(int x, int y)
{
    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;
        // 如果相邻位置有障碍物则返回false
        if (a[nx][ny]==1) return false;
    }
    // 四周都没有障碍物则返回true
    return true;
}

int main()
{
    // 输入地图尺寸n行m列
    cin >> n >> m;
    
    // 读入地图数据
    for (int i=1; i<=n; i++)
        for (int j=1; j<=m; j++)
        {
            char c; cin >> c;
            // 将'#'转换为1表示障碍物,其他为0表示空地
            if (c=='#') a[i][j] = 1;
        }
    
    // 计算初始状态下满足条件的空地数量
    for (int i=1; i<=n; i++)
        for (int j=1; j<=m; j++)
            // 如果是空地且四周没有障碍物
            if (a[i][j]==0 && check(i, j))
                ans++;  // 计数增加
    
    int res = 0;  // 记录最多能新增的满足条件的位置数
    
    // 尝试移除每个障碍物,计算能新增多少满足条件的位置
    for (int i=1; i<=n; i++)
        for (int j=1; j<=m; j++)
        {
            int cnt = 0;  // 记录当前障碍物移除后的新增数量
            if (a[i][j]==1)  // 如果是障碍物
            {
                a[i][j] = 0;  // 临时移除障碍物
                // 检查这个位置本身是否满足条件
                if (check(i, j)) cnt++;
                
                // 检查这个位置四周的空地是否满足条件
                for (int k=0; k<4; k++)
                {
                    int nx = i + dx[k], ny = j + dy[k];
                    // 跳过超出边界的位置
                    if (nx<1 || nx>n || ny<1 || ny>m) continue;
                    // 如果是空地且满足条件
                    if (a[nx][ny]==0 && check(nx, ny)) cnt++;
                }
                
                a[i][j] = 1;  // 恢复障碍物
            }
            res = max(res, cnt);  // 更新最大值
        }
    
    // 输出初始满足条件的位置数加上最多能新增的数量
    cout << ans + res << endl;
    
    return 0;
}

【运行结果】

3 5
.....
.#..#
.....
11

你可能感兴趣的:(c++,算法,开发语言)