题目描述
Description
在一个NN格的棋盘中,有2N-1条从左上角到右下角的斜线,如下图:
由上图我们会发现,每个单元格只且只有一条从左上到右下的斜线经过它。 已知这个N*N的棋盘中,每个格子中都放有一个整数。求某个单元格所在的斜线上所有单元格数值的和。 例如:
例如:第2行第3列的单元格所在的斜线经过了第1行第2列,第2行第3列,和第3行第4列。所以这条斜线所经过的所有单元格数值的和为2+4+9=15。
Input
输入数据有多行。 第一行为一个整数N(2<=N<=100)。表示棋盘的大小。
接下来有N行,每行N个整数,共N*N个整数,表示棋盘中每个格子中的数值,所有数据都小于10^9。
最后还有一行,有两个整数x,y(2<=x,y<=100),表示棋盘中第x行,第y列的位置。
Output
一个整数,求第x行,第y列单元格所在斜线上所有单元格数值的和。
Samples
输入数据 1
4
3 2 2 7
2 4 4 8
5 8 6 9
7 0 4 5
2 3
Copy
输出数据 1
15
总体思路
一、题目分析
棋盘结构:给定一个 的棋盘,其中 的取值范围是未明确给出的正整数。这意味着棋盘的大小在一定范围内,既不会太小导致问题过于简单,也不会太大使得计算变得过于复杂。棋盘中有 条从左上角到右下角的斜线,每条斜线都经过多个单元格。这些斜线的数量与棋盘的大小有关,随着棋盘的增大,斜线的数量也会相应增加。
任务要求:已知每个单元格中都放有一个整数,这些整数的取值范围没有明确给出,但通常可以假设在合理的数值范围内。需要求出指定单元格所在斜线上所有单元格数值的和。这个任务要求我们能够准确地定位到特定的单元格,并找到其所在的斜线,然后计算斜线上所有单元格数值的总和。
二、解题思路
斜线特点观察
对于一个位于第 行第 列的单元格,其所在斜线的重要特征是行号和列号之和是固定的,即 的值是固定的。这一特点是解决问题的关键,因为它提供了一种方法来确定一个单元格是否在特定的斜线上。例如,如果目标单元格是第 2 行第 3 列,那么其行号和列号之和为 5。所有行号和列号之和为 5 的单元格都在同一条斜线上。
遍历策略
遍历整个棋盘,对于每一个单元格,判断其行号和列号之和是否等于目标单元格的行号和列号之和。如果相等,说明该单元格在目标斜线上,将该单元格的值加入到斜线和中。通过这种方式,我们可以逐步累积斜线上所有单元格的数值。
三、代码实现(以 C++ 为例)
#include<bits/stdc++.h>
using namespace std;
long long n,a[105][105],x,y,s;
int main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
scanf("%lld",&a[i][j]);
}
cin>>x>>y;
for(int i=x,j=y;i>=1&&j>=1;i--,j--)
{
s+=a[i][j];
}
for(int i=x,j=y;j<=n&&i<=n;i++,j++)
{
s+=a[i][j];
}
cout<<s-a[x][y];
return 0;
}
四、代码解释
读取棋盘大小
首先,从输入中读取棋盘的大小 。这个值决定了棋盘的维度以及后续需要处理的数据量。例如,如果 ,那么我们将处理一个 的棋盘。这个步骤是程序的起点,它为后续的操作提供了基础。
读取棋盘数值
使用双重循环遍历棋盘的每一行和每一列。外层循环控制行的遍历,内层循环控制列的遍历。对于每个单元格,从输入中读取一个整数,并存储在二维数组 grid
中。这个数组将用于表示棋盘的每个格子中的数值。通过这种方式,我们可以将输入的整数逐个存储到数组中,以便后续进行计算。
读取目标单元格坐标
从输入中读取目标单元格的行号 和列号 。这些坐标将用于确定要计算其所在斜线数值和的特定单元格。例如,如果输入的坐标是 ,,那么我们将计算第 2 行第 3 列单元格所在斜线上的数值和。
初始化斜线和变量
初始化变量 sum
为 0。这个变量将用于存储目标斜线的数值和。在开始计算之前,将和初始化为 0 是一种常见的做法,确保后续的加法操作能够正确地累积数值。
遍历棋盘计算斜线和
使用双重循环再次遍历整个棋盘。这与读取棋盘数值的步骤类似,但目的不同。在这里,我们是为了找到目标斜线上的单元格并计算它们的数值和。对于每个单元格,判断其行号和列号之和是否等于目标单元格的行号和列号之和(即 )。这里的 是因为在计算行号和列号之和时,目标单元格的坐标是从 1 开始的,而在代码中的数组索引是从 0 开始的。如果满足条件,说明该单元格在目标斜线上,将该单元格的值 grid[i][j]
加入到 sum
中。通过这种方式,我们逐步累积斜线上所有单元格的数值。
输出结果
最后,输出 sum
,即目标斜线的数值和。这个结果是程序的最终输出,它满足了题目要求的计算特定单元格所在斜线上所有单元格数值的和。
五、时间复杂度和空间复杂度分析
时间复杂度
代码中使用了双重循环遍历整个棋盘,外层循环遍历 行,内层循环遍历 列,所以总的循环次数为 。对于每个循环,判断行号和列号之和是否等于目标单元格的行号和列号之和的操作是常数时间复杂度。因此,时间复杂度为 。在输入规模较大时,程序的运行时间会随着棋盘大小的平方增长。这意味着当棋盘的大小增加时,程序的运行时间会增长得非常快。
空间复杂度
代码中使用了一个二维数组 grid
存储棋盘的数值,这个数组的大小为 。无论棋盘的大小如何,数组的大小都是与棋盘大小的平方成正比的。因此,空间复杂度为 。这意味着程序需要占用与棋盘大小的平方成正比的内存空间来存储棋盘的数值。当棋盘的大小增加时,所需的内存空间也会迅速增加。