作为一名算法竞赛教练,每年寒暑假的集训都是检验学生阶段性学习成果的重要节点。2月26日这套前三题的设计非常典型,涵盖了动态规划、图论和数据结构三大核心考点,难度梯度设置合理,既考察基础算法掌握程度,又考验临场解题思维。这套题特别适合作为蓝桥杯、ACM-ICPC区域赛的赛前模拟训练。
给定一个N×N的整数矩阵,要求找出其所有子矩阵中的最大和。其中子矩阵定义为矩阵中连续行和列组成的矩形区域。
最直观的解法是枚举所有可能的子矩阵:
采用降维思想将二维问题转化为一维:
python复制def max_submatrix(matrix):
n = len(matrix)
max_sum = -float('inf')
# 预处理列前缀和
col_prefix = [[0]*(n+1) for _ in range(n)]
for i in range(n):
for j in range(n):
col_prefix[i][j+1] = col_prefix[i][j] + matrix[i][j]
# 枚举上下边界
for top in range(n):
for bottom in range(top, n):
# 压缩为一维数组
temp = [0]*n
for k in range(n):
temp[k] = col_prefix[k][bottom+1] - col_prefix[k][top]
# Kadane算法
current = temp[0]
max_temp = temp[0]
for num in temp[1:]:
current = max(num, current + num)
max_temp = max(max_temp, current)
max_sum = max(max_sum, max_temp)
return max_sum
给定一个无向无权图,求从起点s到终点t的最短路径数量。图中可能存在重边和自环。
在标准BFS基础上增加计数功能:
python复制from collections import deque
def count_shortest_paths(graph, s, t):
n = len(graph)
dist = [-1] * n
cnt = [0] * n
dist[s] = 0
cnt[s] = 1
q = deque([s])
while q:
u = q.popleft()
for v in graph[u]:
if dist[v] == -1: # 第一次访问
dist[v] = dist[u] + 1
cnt[v] = cnt[u]
q.append(v)
elif dist[v] == dist[u] + 1: # 最短路径的其他分支
cnt[v] += cnt[u]
return cnt[t]
给定长度为N的数组和M次查询,每次查询给出区间[L,R],要求快速计算该区间内满足某种条件的元素个数。
针对不同查询条件,线段树需要维护不同信息:
以统计区间内奇数为例:
python复制class SegmentTree:
def __init__(self, data):
self.n = len(data)
self.size = 1
while self.size < self.n:
self.size <<= 1
self.tree = [0] * (2 * self.size)
# 初始化叶子节点
for i in range(self.n):
self.tree[self.size + i] = 1 if data[i] % 2 != 0 else 0
# 构建内部节点
for i in range(self.size - 1, 0, -1):
self.tree[i] = self.tree[2*i] + self.tree[2*i+1]
def query(self, l, r):
res = 0
l += self.size
r += self.size
while l <= r:
if l % 2 == 1:
res += self.tree[l]
l += 1
if r % 2 == 0:
res += self.tree[r]
r -= 1
l //= 2
r //= 2
return res
建议提前准备以下模板:
在实际比赛中,我通常会让学生先用30%时间分析题目,50%时间编写调试,最后20%时间检查边界和优化。这套寒假集训题很好地覆盖了算法竞赛中的核心考点,通过系统性地解决这类问题,学生的算法思维和编码能力能得到显著提升。