📜  门|门 CS 1996 |第 73 题(1)

📅  最后修改于: 2023-12-03 15:12:45.867000             🧑  作者: Mango

门|门 CS 1996 |第 73 题

本题是一道计算机编程竞赛中的经典问题,题目要求编写一个程序,能够求解输入的矩阵中每个元素的“门禁值”。

题目描述

假设有一个 $n \times m$ 的矩阵 $A$,其中所有元素的数值都在 $0$ 到 $9$ 之间。矩阵中每个位置都安装了一个“门禁器”,我们定义矩阵中一个位置的“门禁值”为此位置上方和左侧所有门禁器的编号的和。

现有 $q$ 次查询,对于每次查询,给出位置 $(x,y)$,求出此位置的门禁值。

输入格式

第一行包含两个正整数 $n$ 和 $m$,表示矩阵的行数和列数。

接下来 $n$ 行,每行包含 $m$ 个数,表示矩阵 $A$ 中的元素。

接下来一行包含一个正整数 $q$,表示查询次数。

接下来 $q$ 行,每行包含两个正整数 $x$ 和 $y$,表示一次查询的位置。

输出格式

对于每次查询,输出一行,包含一个整数,表示此位置的门禁值。

样例

输入:

3 4
1 2 3 4
5 6 7 8
9 10 11 12
3
1 2
2 3
2 2

输出:

8
21
19
题解思路

对于每次查询,我们需要计算出给定坐标 $(x,y)$ 的“门禁值”。根据题目描述,此位置的门禁值为其上方和左侧所有“门禁器”的编号之和。

对于每次查询,我们可以使用动态规划的思想来计算。首先,我们可以预处理出一个前缀和数组 $s_{i,j}$,表示从左上角到 $(i,j)$ 位置的所有元素之和,即 $s_{i,j} = \sum\limits_{k=1}^i \sum\limits_{l=1}^j a_{k,l}$。然后,对于每个查询位置 $(x,y)$,我们可以计算出其“门禁值”为 $s_{x,y} - s_{x,y-1} - s_{x-1,y} + s_{x-1,y-1}$。

时间复杂度为 $O(nm+q)$。

参考实现
def door_value(n, m, A, queries):
    # 计算前缀和数组
    s = [[0] * (m + 1) for _ in range(n + 1)]
    for i in range(1, n + 1):
        for j in range(1, m + 1):
            s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + A[i - 1][j - 1]

    # 计算每个查询位置的门禁值
    res = []
    for x, y in queries:
        res.append(s[x][y] - s[x][y - 1] - s[x - 1][y] + s[x - 1][y - 1])

    return res

以上代码片段仅供参考。