题解
寻宝闯关游戏
1 条题解
-
0
解题思路
这是一道“二维数组”的基础题,关键是找对两条对角线上的格子。
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