Menu
CoddyTech

山峰

本课属于 Coddy C 学习旅程的“基础知识”单元。第 62 课,共 63 课。

challenge icon

挑战

给你一个由整数高度组成的二维网格,用来表示地形图。如果一个单元格的值严格大于它所有相邻单元格的值(最多有 8 个:北、南、东、西,以及四个对角方向),那么这个单元格就称为峰值

规则

  • 8 个邻居:你必须检查北、南、东、西和四个对角方向。
  • 边界单元格:如果一个单元格位于边缘或角落,它的邻居少于 8 个。只要它严格大于所有存在的邻居,它仍然是峰值。
  • 严格大于:如果某个邻居的高度与当前单元格相同,当前单元格不是峰值。

输入

  • 两个整数 N 和 M,分别表示行数和列数。
  • 一个由整数构成的 N*M 网格

输出

  1. 一个整数,表示峰值的总数。
  2. 每个峰值的坐标(行和列,从 0 开始索引),先按行、再按列排序。

例如,对于以下输入:

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

输出为:

5
0 4
1 0
2 2
4 1
4 3

说明 峰值位于以下位置:

  • (0,4),高度为 4:大于相邻单元格的值(3、1、1)。
  • (1,0),高度为 5:大于相邻单元格的值(1、2、1、1、1)。
  • (2,2),高度为 9:大于周围所有 8 个值为 1 的单元格。
  • (4,1),高度为 3:大于相邻单元格的值(2、1、1、1、1)。
  • (4,3),高度为 4:大于相邻单元格的值(1、1、1、2、1)。

亲手试试

#include <stdio.h>

#define MAXN 100
#define MAXM 100

int N, M;
int grid[MAXN][MAXM];

/**
 * 如果(r, c)处的单元格是峰值,返回 1,否则返回 0。
 * 峰值必须严格大于所有存在的相邻单元格。
 */
int is_peak(int r, int c) {
    // TODO:定义 8 个相邻单元格的相对位置
    // (上、下、左、右,以及 4 个对角方向)。
    
    // TODO:遍历每个相邻单元格。
    // 重要提示:检查 grid[nr][nc] 之前,你必须确保 
    // nr 和 nc 在边界内(0 到 N-1,以及 0 到 M-1)。
    
    return 1; // 占位内容
}

int main() {
    // 读取维度
    if (scanf("%d %d", &N, &M) != 2) {
        return 1;
    }

    // TODO:使用嵌套循环从 stdin 读取网格中的值。
    
    // TODO:遍历网格中的每个单元格(i, j)。
    // 如果 is_peak(i, j) 为真,就保存坐标。
    // 你可以使用 peak_r[MAXN*MAXM] 和 peak_c[MAXN*MAXM] 这样的两个数组 
    // 在打印前存储结果。

    // TODO: 打印峰值的总数。
    
    // TODO: 打印存储的每一对 (row, col)。 
    // 因为你先按行、再按列遍历,它们已经排好序了!

    return 0;
}

基础知识中的所有课

自己练习: C 在线编译器