题意解析
设点 A 坐标 $(a, b)$,点 B 坐标$(c, d)$。
满足:
1. $|a - c| = |b - d|$。
2. $w_{a, b} = w_{c, d}$。
那么 AB 就是一对满足条件的格子。
20pts
- 枚举点 A 可能的情况,时间复杂度 $O(n^2)$。
- 枚举点 B 可能的情况,时间复杂度 $O(n^2)$。
- 判断是否满足上述条件 $1, 2$,时间复杂度 $O(1)$。
总的时间复杂度 $O(n^4)$。
100pts
要优化时间复杂度,必须从条件 $1$ 或条件 $2$ 入手。
条件 $1$ 等价于,AB 两点在同一条斜线上。
如下图的棕色方块,均为在一条斜线上(本条件类似于八皇后的车)。
优化 <条件 1>:
在每一条斜线上进行枚举,判断条件 $2$,这样时间复杂度约为 $n^3$。
优化 <条件 2>:
先预处理出所有值的位置,例如 $value = 3$ 的点位于 $(1, 2)$,$(3, 4)$,$\dots$。
再进行二重循环枚举,判断点是否在一条斜线上,在数据随机的情况下时间复杂度有较大优化,但当所有点的 $valus$ 均相等时,时间复杂度为 $n^4$。
结合上述两个优化
遍历每一条斜线($k = 1$ 或 $k = -1$),在一条斜线上维护之前的值的出现的次数,例如我现在遍历到斜线的第 $5$ 个点,$value = 3$,前 $4$ 个点中,$value = 3$ 的点,均可以与本点进行配对。
由于若 AB 配对,那么一定有 BA 配对,故答案需 $\times 2$。
n, m = map(int, input().split())
g = []
for i in range(n):
lis = list(map(int, input().split()))
g.append(lis)
dx = [1, 1]
dy = [1, -1]
def get_ans(x, y, d):
res = 0
h = {}
while x >= 0 and y >= 0 and x < n and y < m:
v = g[x][y]
if v in h:
res += h[v]
else:
h[v] = 0
h[v] += 1
x += dx[d]
y += dy[d]
return res
res = 0
for j in range(m):
res += get_ans(0, j, 0)
for i in range(1, n):
res += get_ans(i, 0, 0)
for j in range(m):
res += get_ans(0, j, 1)
for i in range(1, n):
res += get_ans(i, m - 1, 1)
print(res * 2)