top1编程
← 返回题目
题解

寻宝闯关游戏

1 条题解

  • 0
    @ 2026-8-5 14:24:32

    解题思路

    这是一道“二维数组”的基础题,关键是找对两条对角线上的格子。

    1. 两条对角线在哪里?

    假设方阵的大小是 n,格子用第 i 行第 j 列表示(1 ≤ i, j ≤ n):

    • 主对角线:从左上角到右下角,格子是 (1,1)、(2,2)、(3,3)、……、(n,n),也就是第 i 行第 i 列。
    • 副对角线:从右上角到左下角,格子是 (1,n)、(2,n-1)、……、(n,1),也就是第 i 行第 n+1-i 列。

    我们只要用一个循环,把 a[i][i] 和 a[i][n+1-i] 都加起来就行了。

    2. 中间的点为什么只算一次?

    如果 n 是奇数,两条对角线会在最中间相遇,正中间那个格子被加了两次。题目要求“中间的点只计算一次”,所以要把正中间的格子减掉一次。中间格子的位置是 (n/2+1, n/2+1)(整数除法会自动向下取整,比如 5/2 得 2)。

    3. 小提醒

    • 数组要开大一点,比如 a[105][105],这样 n ≤ 100 时不会越界。
    • 行和列都从 1 开始编号,计算副对角线 n+1-i 时就不会弄混。

    参考代码

    #include <iostream>
    using namespace std;
    int a[105][105];
    int main(){
        // P4520 寻宝闯关游戏:求两条对角线数字之和,n为奇数时中间点只算一次
        int n;
        cin >> n;
        // 读入 n*n 数字方阵(用 1 到 n 编号)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                cin >> a[i][j];
        int sum = 0;
        // 主对角线 a[i][i] + 副对角线 a[i][n+1-i]
        for(int i=1;i<=n;i++)
            sum += a[i][i] + a[i][n+1-i];
        // n 为奇数时,正中间的点被加了两次,要减掉一次
        if(n%2==1)
            sum -= a[n/2+1][n/2+1];
        cout << sum << endl;
        return 0;
    }
    

    复杂度分析

    • 读入方阵:一共有 n×n 个数,需要 O(n²) 的时间。
    • 求和:两条对角线上一共有 2n 个格子(正中间的可能算两次),只需要一次循环,时间是 O(n)。

    所以整个程序的时间复杂度是 O(n²)。n 最大是 100,最多计算 100×100=10000 次,非常快。数组只开了一个 105×105 的二维数组,空间复杂度也是 O(n²)。

    • 1