题解
N字上的数字和
1 条题解
-
0
解题思路
“N”字由三部分组成:
- 最左边一列(第 1 列);
- 最右边一列(第 n 列);
- 主对角线(从左上角 (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