3360:【例62.2】 相邻数之和

这道题目是二维数组基础练习中的经典题型,主要考察对数组下标的控制以及边界条件的判定


题目解析:相邻数之和 (3360)

1. 题目逻辑分析

题目要求计算二维数组中某个指定点 \((c, r)\) 周围 8 个方向相邻元素的总和。

所谓的“相邻元素”,是指在坐标上与目标点相差不超过 1 的点。假设目标点坐标为 \((x, y)\),那么它的潜在邻居坐标范围是:

  • 行下标:从 \(x-1\)\(x+1\)
  • 列下标:从 \(y-1\)\(y+1\)

注意: 目标点本身 \((x, y)\) 不计入总和。

2. 核心难点:边界判定

这是本题最容易出错的地方。由于目标点可能在数组的四个角四条边上,直接计算 \(x-1\)\(y+1\) 可能会导致数组越界

我们需要在累加之前,判断邻居坐标 \((nx, ny)\) 是否满足:

  1. \(0 \le nx < h\) (行不越界)
  2. \(0 \le ny < l\) (列不越界)
  3. \((nx, ny) \neq (c, r)\) (排除自身)

3. C++ 代码实现

这里提供一种使用“方向数组”的优雅写法,这种方法在后续学习搜索算法(DFS/BFS)时非常通用。

#include <iostream>
using namespace std;

int main() {
    int h, l, c, r;
    // 读取行列数及目标点坐标
    cin >> h >> l >> c >> r;

    int a[15][15]; // 根据题目范围 2<=h,l<=10,开 15 足够
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < l; j++) {
            cin >> a[i][j];
        }
    }

    long long sum = 0;

    // 遍历以 (c, r) 为中心的 3x3 区域
    for (int i = c - 1; i <= c + 1; i++) {
        for (int j = r - 1; j <= r + 1; j++) {
            // 判定 1: 必须在数组范围内
            if (i >= 0 && i < h && j >= 0 && j < l) {
                // 判定 2: 不能是目标点本身
                if (!(i == c && j == r)) {
                    sum += a[i][j];
                }
            }
        }
    }

    cout << sum << endl;

    return 0;
}

4. 关键点总结

  • 输入顺序:题目给出的输入顺序是 \(h, l, c, r\),先是地图大小,再是坐标,读取时不要弄反。
  • 坐标系:程序中习惯使用 i 代表行(对应 \(h\)\(c\)),j 代表列(对应 \(l\)\(r\))。
  • 双重循环:通过 c-1c+1 的循环,可以一次性覆盖周围所有点,配合 if 判定即可过滤掉非法位置。
posted @ 2026-02-05 18:18  张一信奥  阅读(6)  评论(0)    收藏  举报