蓝桥杯python每日刷题 day seven

题目:

小蓝正在和朋友们玩一种新的连连看游戏。在一个 n × m 的矩形网格中,每个格子中都有一个整数,第 i 行第 j 列上的整数为 Ai, j 。玩家需要在这个网格中寻找一对格子 (a, b) − (c, d) 使得这两个格子中的整数 Aa,b 和 Ac,d 相等(即第a行第b列和第c行第d列相同)且它们的位置满足 |a − c| = |b − d| > 0(即两个数在同一个对角线上) 。请问在这个 n × m 的矩形网格中有多少对这样的格子满足条件。

此处补充对角线分为主对角线和副对角线,主为从左上角到右下角,为i - j,副则为从右上角到左下角,为i + j

(1)代码:

n, m = map(int, input().split())

N = int(2e3+5)

(2e3为科学计数法,意为【2 * (10 **3)】 + 5)

st1 = [[0] * N for _ in range(N)]

st2 = [[0] * N for _ in range(N)】

  • (定义两个二维数组 st1 和 st2,用于记录每条对角线上每个值的出现次数。
    • st1 用于主对角线(满足 i−j=常数)。
    • st2 用于副对角线(满足 i+j=常数))。

arr = []

for _ in range(n):

    arr += [list(map(int, input().split()))]

(用于将网格的每一个元素储存在arr中)

for i in range(n):

    for j in range(m):

        st1[i - j + 1000][arr[i][j]] += 1

        st2[i + j][arr[i][j]] += 1

此处为统计出现在同一对角线上的同一个数值的次数

示例

输入网格:
1 2 3
4 1 6
7 8 1
处理过程:
  1. 格子 (0,0)=1

    • 主对角线:i - j = 0 - 0 = 0i - j + 1000 = 1000
      • st1[1000][1] += 1st1[1000][1] = 1
    • 副对角线:i + j = 0 + 0 = 0
      • st2[0][1] += 1st2[0][1] = 1
  2. 格子 (0,1)=2

    • 主对角线:i - j = 0 - 1 = -1i - j + 1000 = 999
      • st1[999][2] += 1st1[999][2] = 1
    • 副对角线:i + j = 0 + 1 = 1
      • st2[1][2] += 1st2[1][2] = 1
  3. 格子 (0,2)=3

    • 主对角线:i - j = 0 - 2 = -2i - j + 1000 = 998
      • st1[998][3] += 1st1[998][3] = 1
    • 副对角线:i + j = 0 + 2 = 2
      • st2[2][3] += 1st2[2][3] = 1
  4. 格子 (1,0)=4

    • 主对角线:i - j = 1 - 0 = 1i - j + 1000 = 1001
      • st1[1001][4] += 1st1[1001][4] = 1
    • 副对角线:i + j = 1 + 0 = 1
      • st2[1][4] += 1st2[1][4] = 1
  5. 格子 (1,1)=1

    • 主对角线:i - j = 1 - 1 = 0i - j + 1000 = 1000
      • st1[1000][1] += 1st1[1000][1] = 2
    • 副对角线:i + j = 1 + 1 = 2
      • st2[2][1] += 1st2[2][1] = 1
  6. 格子 (1,2)=6

    • 主对角线:i - j = 1 - 2 = -1i - j + 1000 = 999
      • st1[999][6] += 1st1[999][6] = 1
    • 副对角线:i + j = 1 + 2 = 3
      • st2[3][6] += 1st2[3][6] = 1
  7. 格子 (2,0)=7

    • 主对角线:i - j = 2 - 0 = 2i - j + 1000 = 1002
      • st1[1002][7] += 1st1[1002][7] = 1
    • 副对角线:i + j = 2 + 0 = 2
      • st2[2][7] += 1st2[2][7] = 1
  8. 格子 (2,1)=8

    • 主对角线:i - j = 2 - 1 = 1i - j + 1000 = 1001
      • st1[1001][8] += 1st1[1001][8] = 1
    • 副对角线:i + j = 2 + 1 = 3
      • st2[3][8] += 1st2[3][8] = 1
  9. 格子 (2,2)=1

    • 主对角线:i - j = 2 - 2 = 0i - j + 1000 = 1000
      • st1[1000][1] += 1st1[1000][1] = 3
    • 副对角线:i + j = 2 + 2 = 4
      • st2[4][1] += 1st2[4][1] = 1
最终结果:
  • ​**st1**​(主对角线):

    • st1[1000][1] = 3(主对角线 0,值 1 出现 3 次)。
    • st1[999][2] = 1(主对角线 -1,值 2 出现 1 次)。
    • st1[998][3] = 1(主对角线 -2,值 3 出现 1 次)。
    • st1[1001][4] = 1(主对角线 1,值 4 出现 1 次)。
    • st1[999][6] = 1(主对角线 -1,值 6 出现 1 次)。
    • st1[1002][7] = 1(主对角线 2,值 7 出现 1 次)。
    • st1[1001][8] = 1(主对角线 1,值 8 出现 1 次)。
  • ​**st2**​(副对角线):

    • st2[0][1] = 1(副对角线 0,值 1 出现 1 次)。
    • st2[1][2] = 1(副对角线 1,值 2 出现 1 次)。
    • st2[2][3] = 1(副对角线 2,值 3 出现 1 次)。
    • st2[1][4] = 1(副对角线 1,值 4 出现 1 次)。
    • st2[2][1] = 1(副对角线 2,值 1 出现 1 次)。
    • st2[3][6] = 1(副对角线 3,值 6 出现 1 次)。
    • st2[2][7] = 1(副对角线 2,值 7 出现 1 次)。
    • st2[3][8] = 1(副对角线 3,值 8 出现 1 次)。
    • st2[4][1] = 1(副对角线 4,值 1 出现 1 次)

ans = 0

for i in range(n):

    for j in range(m):

        ans += st1[i - j + 1000][arr[i][j]] - 1

        ans += st2[i + j][arr[i][j]] - 1

st2[i + j][arr[i][j]]**:表示在副对角线 i+j 上,值 arr[i][j] 的出现次数。

- 1**:减去 1,排除当前格子本身。

举例

输入网格:
1 2 3
4 1 6
7 8 1

格子 (0,0)=1

  • 主对角线:st1[1000][1] = 3
    • 满足条件的格子对数量:3 - 1 = 2
  • 副对角线:st2[0][1] = 1
    • 满足条件的格子对数量:1 - 1 = 0
  • 更新 ansans += 2 + 0 = 2
  • 在主对角线中3-1意为只用两对满足条件,而1-1意为在(i+j)为0的副对角线中,没有跟1一样的值,所以为0对

print(ans)

(2)解析:

接下来对全行进行解析

你可能感兴趣的:(蓝桥杯,职场和发展)