GESP2026年3月认证C++四级( 第三部分编程题(1) 山之谷)
🌄《山谷探险记》——编程题第一题讲解
🧙 一、故事背景
1、小明来到一片神秘山地:
每个格子都有一个高度2、就像这样:
7 6 6 7 9 6 5 6 7 6 6 5 7 8 93、🌱 小明要找的是:
👉“山谷”
🌟 二、什么是“山谷”?
1、🧠 定义
👉 一个格子,如果:
它 ≤ 周围所有8个方向的格子
那它就是山谷!
2、📦 8个方向是哪些?
左 上 右 左 右 左 下 右3、也就是:
⬅️ ➡️ ⬆️ ⬇️ ↖️ ↗️ ↙️ ↘️🎯 三、任务目标
👉 统计:一共有多少个山谷
🧪 四、用样例来理解
7 6 6 7 9 6 5 6 7 6 6 5 7 8 91、我们来找山谷 👇
2、从头到尾看一遍:
(1)🔍 看 (2,2) = 5
周围是:
7 6 6 6 6 6 5 7👉 它是最小的!
✔ 是山谷!
(2)全部都找完,最终找到3个山谷
(3)🎉 所以答案是:
3🧠 五、核心思路
🎯 每个格子都要检查!
👉 对每个 (i, j):
1️⃣ 假设它是山谷
2️⃣ 检查周围8个方向
3️⃣ 如果有比它小的 → ❌ 不是
4️⃣ 如果都 ≥ 它 → ✅ 是山谷
⚠️ 六、难点:边界问题!
1、🧙 故事
地图边缘没有邻居怎么办?
👉 比如左上角!
2、💡 解决方法
👉 在地图外面包一圈“超级高山”:
h[i][0]=h[0][i]=h[i][m+1]=h[n+1][i]=1e9;这样:
👉 边界就安全了!
🎉 七、参考程序:
#include<iostream> using namespace std; int main(){ int n,m; cin>>n>>m; int h[105][105]; // 读入 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>h[i][j]; // 加围墙 for(int i=0;i<=max(n,m)+1;i++) h[i][0]=h[0][i]=h[i][m+1]=h[n+1][i]=1e9; int ans=0; // 遍历每个点 for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ bool ok=true; // 检查周围8个方向 for(int i2=i-1;i2<=i+1;i2++){ for(int j2=j-1;j2<=j+1;j2++){ if(h[i][j]>h[i2][j2]){ ok=false; } } } if(ok) ans++; } } cout<<ans; return 0; }🧩 八、详细讲解
1、🌟 第一步:读入地图
int n, m; cin >> n >> m; int h[105][105]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin >> h[i][j];2、🌟 第二步:加“围墙”
for(int i=0;i<=max(n,m)+1;i++){ h[i][0] = h[0][i] = h[i][m+1] = h[n+1][i] = 1e9; }👉 外面一圈都是超级大!
3、🌟 第三步:检查每个点
int ans = 0; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){4、🌟 第四步:判断是不是山谷
bool ok = true; for(int i2=i-1;i2<=i+1;i2++){ for(int j2=j-1;j2<=j+1;j2++){ if(h[i][j] > h[i2][j2]){ ok = false; } } }👉 只要发现有更小的邻居 → 失败!
5、🌟 第五步:统计答案
ans += ok;👉 true = 1
👉 false = 0
6、🌟 第六步:输出
cout << ans;🚀 九、考点总结
✅ 二维数组遍历
✅ 8方向枚举
✅ 边界处理技巧(超级重要!)
✅ 模拟题思维
🎁 十、记忆口诀!
🌟 山谷判断口诀:
自己最小才算谷 八方邻居都要顾 边界加墙防越界 全部检查不马虎