GESP认证C++编程真题解析 | 202603 四级

编程题

B4501 山之谷

【题目来源】

洛谷:[B4501 GESP202603 四级] 山之谷 - 洛谷

【题目描述】

现有一片山地,可以视为一个 \(N\)\(M\) 列的网格图,第 \(i\)\(j\) 列的海拔为 \(h_{i,j}\)

如果一个单元格的海拔不高于其所有相邻单元格(相邻包括上、下、左、右、左上、右上、左下、右下,最多 \(8\) 个方向)的海拔,则称该单元格为山谷。

请你数一数该片山地中有多少山谷。

【输入】

第一行包含 \(2\) 个整数 \(N, M\),表示山地的大小。

之后 \(N\) 行,每行包含 \(M\) 个整数 \(h_{i,1}, h_{i,2}, \cdots, h_{i,M}\),表示海拔。

【输出】

输出 \(1\) 行,包含 \(1\) 个整数 \(C\),表示山谷的数量。

【输入样例】

3 5
7 6 6 7 9
6 5 6 7 6
6 5 7 8 9

【输出样例】

3

【算法标签】

《洛谷 B4501 山之谷》 #枚举# #GESP# #2026#

【代码详解】

#include <bits/stdc++.h>  // 包含所有标准库头文件
using namespace std;       // 使用标准命名空间

const int N = 105;  // 定义常量N,表示数组最大尺寸
int n, m, cnt;      // n:行数, m:列数, cnt:山谷计数器
int a[N][N];        // 定义二维数组a,存储地形高度

// 定义8个方向向量,用于访问当前位置周围的8个邻居
int dx[8] = {-1, -1, -1, 0, 1, 1, 1, 0};  // x方向偏移:左、左上、上、右上、右、右下、下、左下
int dy[8] = {-1, 0, 1, 1, 1, 0, -1, -1};  // y方向偏移:上、上、上、右、右、右、下、下

int main()  // 主函数入口
{
    cin >> n >> m;  // 输入矩阵的行数n和列数m
    
    // 读取矩阵数据
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            cin >> a[i][j];  // 读取第i行第j列的高度
        }
    }
    
    // 遍历矩阵中的每一个位置
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            bool flag = 1;  // 标志位,表示当前位置是否是山谷,初始化为true
            
            // 检查当前位置的8个邻居
            for (int k = 0; k < 8; k++)
            {
                // 计算邻居位置的坐标
                int nx = i + dx[k];  // 邻居的x坐标
                int ny = j + dy[k];  // 邻居的y坐标
                
                // 检查邻居是否在矩阵范围内
                if (nx < 1 || nx > n || ny < 1 || ny > m)
                {
                    continue;  // 如果邻居越界,跳过这个邻居
                }
                
                // 检查山谷条件:如果邻居高度小于当前位置高度,则不是山谷
                if (a[nx][ny] < a[i][j])
                {
                    flag = 0;  // 标记当前位置不是山谷
                    break;     // 提前退出循环,不再检查其他邻居
                }
            }
            
            // 如果flag仍为1,说明所有邻居都不小于当前位置,当前位置是山谷
            if (flag)
            {
                cnt++;  // 山谷计数器加1
            }
        }
    }
    
    cout << cnt << endl;  // 输出山谷的总数量
    return 0;  // 程序正常结束
}

【运行结果】

3 5
7 6 6 7 9
6 5 6 7 6
6 5 7 8 9
3

B4502 礼盒排序

【题目来源】

洛谷:[B4502 GESP202603 四级] 礼盒排序 - 洛谷

【题目描述】

商店推出了许多礼盒,每个礼盒中包含 \(k\) 件商品,每件商品都有一个价格。

现在需要对这些礼盒进行排序,排序规则如下:

  1. 先按礼盒总价格从小到大排序;
  2. 如果总价格相同,按礼盒中最贵商品的价格从小到大排序;
  3. 如果仍然相同,按礼盒中最便宜商品的价格从小到大排序;
  4. 如果仍然相同,按礼盒编号从小到大排序。

请输出排序后的礼盒编号。

【输入】

第一行包含两个整数 \(n\)\(k\),分别表示礼盒数量和每个礼盒中商品的数量。

接下来 \(n\) 行,每行包含 \(k\) 个整数,第 \(i\) 行表示第 \(i\) 个礼盒中各商品的价格。

【输出】

输出一行,包含排序后的礼盒编号(编号从 \(1\) 开始),用空格分隔。

【输入样例】

4 3
3 5 2
4 1 5
2 2 4
3 4 3

【输出样例】

3 4 2 1

【算法标签】

《洛谷 B4502 礼盒排序》 #排序# #GESP# #2026#

【代码详解】

#include <bits/stdc++.h>  // 包含所有标准库头文件
using namespace std;       // 使用标准命名空间

const int N = 1005;  // 定义常量N,表示最大学生数量

int n, k;  // n: 学生数量, k: 每个学生的成绩数量

// 定义学生结构体
struct Node
{
    int id;    // 学生编号
    int maxn;  // 该学生的最高成绩
    int minn;  // 该学生的最低成绩
    int tot;   // 该学生的总成绩
} a[N];  // 声明结构体数组a,用于存储所有学生的信息

// 自定义比较函数,用于排序
bool cmp(Node x, Node y)
{
    // 第一优先级:按总成绩从小到大排序
    if (x.tot != y.tot)
    {
        return x.tot < y.tot;
    }
    // 第二优先级:总成绩相同,按最高成绩从小到大排序
    else if (x.maxn != y.maxn)
    {
        return x.maxn < y.maxn;
    }
    // 第三优先级:总成绩和最高成绩都相同,按最低成绩从小到大排序
    else if (x.minn != y.minn)
    {
        return x.minn < y.minn;
    }
    // 第四优先级:所有成绩都相同,按学号从小到大排序
    return x.id < y.id;
}

int main()  // 主函数入口
{
    cin >> n >> k;  // 输入学生数量n和每个学生的成绩数量k
    
    // 读取每个学生的k个成绩
    for (int i = 1; i <= n; i++)
    {
        int x;  // 临时变量,用于读取每个成绩
        cin >> x;  // 读取第一个成绩
        
        int mx, mn, sum = 0;  // mx: 最高成绩, mn: 最低成绩, sum: 总成绩
        mx = mn = x;  // 初始化最高成绩和最低成绩为第一个成绩
        sum += x;     // 将第一个成绩加入总成绩
        
        // 读取剩余的k-1个成绩
        for (int j = 2; j <= k; j++)
        {
            cin >> x;        // 读取下一个成绩
            sum += x;        // 将成绩加入总成绩
            
            // 更新最高成绩
            if (x > mx)
            {
                mx = x;
            }
            
            // 更新最低成绩
            if (x < mn)
            {
                mn = x;
            }
        }
        
        // 将计算得到的值存入结构体数组
        a[i].id = i;      // 学号(从1开始的序号)
        a[i].maxn = mx;   // 最高成绩
        a[i].minn = mn;   // 最低成绩
        a[i].tot = sum;   // 总成绩
    }
    
    // 使用自定义比较函数对数组进行排序
    // 注意:数组下标从1开始,所以排序范围是a+1到a+n+1
    sort(a + 1, a + n + 1, cmp);
    
    // 输出排序后的学号
    for (int i = 1; i <= n; i++)
    {
        cout << a[i].id << " ";
    }
    cout << endl;  // 输出换行
    
    return 0;  // 程序正常结束
}

【运行结果】

4 3
3 5 2
4 1 5
2 2 4
3 4 3
3 4 2 1
posted @ 2026-03-18 16:08  团爸讲算法  阅读(51)  评论(0)    收藏  举报