蓝桥杯 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