top1编程
← 返回题目
题解

N字上的数字和

1 条题解

  • 0
    @ 2026-8-5 0:56:09

    解题思路

    “N”字由三部分组成:

    1. 最左边一列(第 1 列);
    2. 最右边一列(第 n 列);
    3. 主对角线(从左上角 (1,1) 到右下角 (n,n) 的一条斜线)。

    最大的坑在角落:左上角 (1,1) 和右下角 (n,n) 这两个格子,既在最左边/最右边的列上,又在对角线上。如果三部分都加,它们会被加两遍,答案就错了。

    解决办法:对角线上只加中间那些格子——也就是第 2 行到第 n-1 行的 a[i][i]。两个角已经由第 1 列和第 n 列加过了,不会再重复。

    这道题我们可以一边读一边累加:读入每个数字 x(它在第 i 行第 j 列),只要满足下面的任一条件就把它加进总和:

    • j == 1(在最左边一列);
    • j == n(在最右边一列);
    • i == j 且 i 不是 1 也不是 n(在“中间的对角线”上)。

    用 long long 存总和,养成好习惯,防止数特别大时溢出。

    参考代码

    // P4458 N字上的数字和:读入每个数,若它在第1列/第n列/主对角线上就累加
    // 注意两个角(1,1)和(n,n)属于两条线,只加一次(用条件i!=1&&i!=n避开对角线部分)
    #include <iostream>
    using namespace std;
    
    int main() {
        int n, x;
        cin >> n;
        long long s = 0; // 数字总和(可能较大,用long long更安全)
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                cin >> x;
                // 属于N字:第1列、第n列,或主对角线(但排除两个角)
                if (j == 1 || j == n || (i == j && i != 1 && i != n)) s += x;
            }
        }
        cout << s << endl;
        return 0;
    }
    

    复杂度分析

    • 每个格子只读一次,边读边判断是否属于“N”字,时间复杂度是 O(n²)。
    • 不需要把整个方阵存下来,空间复杂度是 O(1)。
    • 1