美团2024年春招第一场笔试【算法策略】第一题解答

146 阅读2分钟

题目:

image.png

image.png

本题可以使用前缀和思想来降低时间复杂度,否则按照题目直接构建解法,复杂度过高,下面是高复杂度的例子:

n = int(input())

matrix = []
for _ in range(n):
    s = input()
    matrix.append(s)

if n == 1:
    print(0)

def pefect(X):
    l = len(X)
    s = ''
    for i in X:
        s += i
    all = 0
    for j in s:
        all += int(j)
    if all == l**2 * 0.5:
        return True
    else:
        return False

for i in range(n):
    edge = i+1
    if edge % 2 == 1:
        print(0)
    if edge % 2 == 0:
        res = 0
        for j in range(n-edge+1):
            top = j
            bottom = top + edge
            M_temp = matrix[top:bottom]
            for k in range(n-edge+1):
                M = []
                left = k
                right = left + edge
                for l in range(edge):
                    M.append(M_temp[l][left:right])
                if pefect(M):
                    res += 1
        print(res)

前缀和思想: 为了快速计算子矩阵的元素和,可以使用二维的前缀和(prefix sum)技巧。前缀和可以让我们在常数时间内得到任意子矩阵的元素和。这样就可以避免每次都重新计算子矩阵的元素总和。 改进后的代码:

n = int(input())

matrix = []
for _ in range(n):
    s = input()
    matrix.append([int(x) for x in s])

# 构建前缀和矩阵
prefix_sum = [[0] * (n+1) for _ in range(n+1)]
for i in range(1, n+1):
    for j in range(1, n+1):
        prefix_sum[i][j] = matrix[i-1][j-1] + prefix_sum[i-1][j] + prefix_sum[i][j-1] - prefix_sum[i-1][j-1]

# 判断子矩阵是否满足条件
def is_perfect(x1, y1, x2, y2):
    # 利用前缀和快速计算矩阵 (x1, y1) 到 (x2, y2) 的子矩阵和
    total = prefix_sum[x2][y2] - prefix_sum[x1-1][y2] - prefix_sum[x2][y1-1] + prefix_sum[x1-1][y1-1]
    size = (x2 - x1 + 1) * (y2 - y1 + 1)
    return total == size * 0.5

if n == 1:
    print(0)
else:
    for edge in range(1,n+1):
        if edge % 2 == 1:
            print(0)
        else:
            res = 0
            for i in range(1, n-edge+2):
                for j in range(1, n-edge+2):
                    if is_perfect(i, j, i+edge-1, j+edge-1):
                        res += 1
            print(res)

复杂度从O(n4)O(n^4)降低到了O(n3)O(n^3)。 下面给出前缀和的计算公式,比较简单:

image.png

image.png