蓝桥杯 2024 省赛 Python B 连连看题目解法解析:暴力解与高效正解探讨

题目描述

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

输入格式

输入的第一行包含两个正整数 n 和 m,用一个空格分隔。

接下来是 n 行,第 i 行包含 m 个正整数 Ai,1​,Ai,2​,…,Ai,m​,相邻整数之间用一个空格分隔。

输出格式

输出一行包含一个整数表示答案。

输入输出样例

输入 #1复制

3 2 
1 2 
2 3 
3 2

输出 #1复制

6

说明/提示

一共有以下 6 对格子:(1,2)−(2,1),(2,2)−(3,1),(2,1)−(3,2),(2,1)−(1,2),(3,1)−(2,2),(3,2)−(2,1)。

数据范围

对于 20% 的评测用例,1≤n,m≤50;

对于所有评测用例,1≤n,m≤1000,1≤Ai,j​≤1000。

暴力解:

        因为蓝桥杯的赛制与acm不同,通过部分的用例可以获得部分的分数,力求省赛获奖而不求进入国赛的选手(up),对于不会的题可以按照题意直接暴力求解,for循环只管套;例如本题中,需要找到满足|a-c| = |b -d|>0且整数A相等的格子的对数,暴力求解就完全遍历棋盘中的每一个整数,让它与其他的每一个整数运算一遍 ,看两者是否满足条件,满足就累加到ans中。

        

n,m = map(int,input().split())
matrix = []
for i in range(n):
    row = list(map(int,input().split()))
    matrix.append(row)

ans = 0
for i in range(n):
    for j in range(m):
        for ii in range(n):
            for jj in range(m):
                if (matrix[i][j] == matrix[ii][jj] and abs(i-ii) == abs(j-jj) and abs(i-ii) > 0):
                    ans += 1

print(ans)

因为涉及到两对坐标的运算,直接套4层循环,暴力解决,在暴力的同时加上剪枝等操作,就可以通过更多的用例,甚至是全部的用例,不过剪枝需要理解题目,去除不必要的循环,这一点就是题目的难点了,例如:

(b站)

n,m = map(int,input().split())
matrix = []
for i in range(n):
    row = list(map(int,input().split()))
    matrix.append(row)

ans = 0
l = [[0] * (2005) for _ in range(2005)]
r = [[0] * (2005) for _ in range(2005)]

for i in range(n):
    for j in range(m):
        ans += l[matrix[i][j]][i+j]
        ans += r[matrix[i][j]][i-j]
        l[matrix[i][j]][i + j] += 1
        r[matrix[i][j]][i - j] += 1

print(ans*2)

还有别的思路,一个题可能有很多解法:

(解法来自C语言网)

m,n = map(int,input().split())  #m行n列
ans = 0
arr = []
for _ in range(m):
    arr.append([int(i) for i in input().strip().split()])
#两条对角线,每条两个三角区域
#1
for i in range(m):  #(i,j)为这条对角线的起点
    temp = {}  #这一条对角线中每个数字出现的次数
    t = 0
    j = 0
    while 0<=i<m and 0<=j<n:
        if arr[i][j] in temp:
            t += temp[arr[i][j]]  #相当与将这次的数字与之前所有数字配一次对
        else:
            temp[arr[i][j]] = 0
        temp[arr[i][j]] += 1 #if和else两种情况都要执行
        i -= 1
        j += 1
    ans += t
#2
for i in range(m):
    temp = {}
    t = 0
    j = 0
    while 0<=i<m and 0<=j<n:
        if arr[i][j] in temp:
            t += temp[arr[i][j]]
        else:
            temp[arr[i][j]] = 0
        temp[arr[i][j]] += 1
        i += 1
        j += 1
    ans += t
#3
for j in range(1,n):
    temp = {}
    t = 0
    i = m-1
    while 0<=i<m and 0<=j<n:
        if arr[i][j] in temp:
            t += temp[arr[i][j]]
        else:
            temp[arr[i][j]] = 0
        temp[arr[i][j]] += 1
        i -= 1
        j += 1
    ans += t
#4
for j in range(1,n):
    temp = {}
    t = 0
    i = 0
    while 0<=i<m and 0<=j<n:
        if arr[i][j] in temp:
            t += temp[arr[i][j]]
        else:
            temp[arr[i][j]] = 0
        temp[arr[i][j]] += 1
        i += 1
        j += 1
    ans += t
print(ans*2)

作者:About1263

物联沃分享整理
物联沃-IOTWORD物联网 » 蓝桥杯 2024 省赛 Python B 连连看题目解法解析:暴力解与高效正解探讨

发表回复