题目:
阿坤老师是学校的数学老师,他特别喜欢让学生挑战一些有趣的数学问题。今天,他给学生带来了一个巨大的魔方。这个魔方的每个面都是一个N×N 的方阵,每个小格子上都填有一个整数。
阿坤老师允许学生按行或者按列,将魔方的一个面上的所有行或者所有列,循环移动若干个位置。他希望学生通过移动行或列,使得主对角线(左上角到右下角)上的数字之和最大。
请问,应该如何移动,才能得到最大的主对角线数字之和?
输入格式
第一行包含一个整数 N,表示魔方的一个面上方阵的大小。
接下来的 N 行,每行包含 N 个整数,表示方阵的每个元素。
输出格式
输出一个整数,表示最大可能的主对角线元素之和。
样例输入
3
7 8 9
4 5 7
1 2 3
样例输出
16
说明
对于样例 我们可以将第3行整体下移一行变换为 ,此时主对角线为元素之和为 1+8+7=16。
答案如下:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int N;
scanf("%d", &N);//对于这定义数组有疑惑的小伙们,我会在下文做出解惑。
int arry[N][N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
scanf("%d", &arry[i][j]);
}
}
int maxSum = 0;
for (int k = 0; k < N; k++) {
int sum = 0;
for (int i = 0; i < N; i++) {
sum += arry[(i + k) % N][i];//这里可以分别得到主对角线上的值。
}
if (sum > maxSum) {
maxSum = sum;
}
}
printf("%d\n", maxSum);
return 0;
}
有些初学者在使用变长数组时会像下面一样书写代码:
int n;
int arry[n];
scanf("%d",&n);
先定义一个变量 n 和一个数组 arry,然后用 scanf() 读入 n 的值。有些初学者认为,scanf() 输入结束后,n 的值就确认下来了,数组 arr 的长度也随即确定了。这种想法看似合理,其实是毫无根据的。
其实从你定义数组的那一刻起(也就是第二行代码),数组的长度就确定下来了,以后再也不会改变了;改变 n 的值并不会影响数组长度,它们之间没有任何“联动”关系。用 scanf() 读入 n 的值,影响的也仅仅是 n 本身,不会影响数组。
而且n 是未初始化的局部变量,它的值是未知的,所以也导致数组的长度也是未知的。
那么修改方式是什么呢?如下:
int n;
scanf("%d",&n);
int arry[n];
在定义数组之前定义n的值,就可以解决该问题了。