📌 写在前面 :今天的题目全部来自蓝桥杯算法赛真题 ,难度直接对标国赛!涵盖了差分数组进阶应用 、贪心策略 、二分查找 、优先队列 、大数运算等核心考点。这些题目不仅是国赛的高频考点,更是区分省一和国一的关键分水岭!
📚 今日刷题清单
| 题号 | 题目 | 类型 | 难度 | 核心考点 |
|---|---|---|---|---|
| 1 | 字符迁移 | 蓝桥杯17164 | ⭐⭐⭐ | 差分数组、循环移位 |
| 2 | 食堂 | 蓝桥杯19724 | ⭐⭐⭐⭐ | 贪心、分类讨论 |
| 3 | X进制减法 | 蓝桥杯2108 | ⭐⭐⭐⭐ | 大数运算、进制转换 |
| 4 | 巧克力 | 蓝桥杯1596 | ⭐⭐⭐⭐⭐ | 贪心、优先队列、堆 |
| 5 | 管道 | 蓝桥杯3544 | ⭐⭐⭐⭐⭐ | 二分查找、区间合并 |
一、核心算法速查
1.1 差分数组进阶
python
# 基础差分:区间加法
diff[l] += k
diff[r+1] -= k
# 进阶差分:循环移位(字符迁移)
# 将字符转换为数字,差分后还原,再转回字符
1.2 贪心策略
python
# 策略1:能配对就配对(食堂问题)
# 策略2:从后往前,优先队列(巧克力问题)
# 策略3:局部最优推全局最优
1.3 二分查找模板
python
# 找最小满足条件的值
left, right = 0, max_val
while left < right:
mid = (left + right) // 2
if check(mid): # mid满足条件
right = mid # 尝试更小
else:
left = mid + 1 # 需要更大
print(left)
二、例题精讲
例题 1:字符迁移 ⭐差分进阶
| 项目 | 内容 |
|---|---|
| 链接 | https://www.lanqiao.cn/problems/17164/learning/ |
| 类型 | 差分数组 + 循环移位 |
| 核心 | 将字符转为数字,差分处理循环移位,再转回字符 |
题目描述
给定字符串, q q q 次操作,每次将区间 [ l , r ] [l,r] [l,r] 的字符向后移动 k k k 位(循环)。
关键思路
将字符问题转化为数字问题:
- 字符转数字:
'a' -> 0, 'b' -> 1, ..., 'z' -> 25 - 差分数组处理区间加法(对26取模)
- 还原前缀和,数字转回字符
推演验证
输入: n=5, s="abcde", q=1
操作: [1,3,2] # 将[1,3]的字符后移2位
字符转数字:a=0, b=1, c=2, d=3, e=4
差分操作后还原:s = [3, 4, 5, 4, 0]
结果: "defea" ✓
题解
python
n, q = map(int, input().split())
s = [0] + list(input()) # 1-indexed
diff = [0] * (n + 2)
# 字符转数字,构建差分数组
for i in range(1, n + 1):
s[i] = ord(s[i]) - 97
diff[i] = s[i] - s[i - 1]
# q次操作
for _ in range(q):
l, r, k = map(int, input().split())
k = k % 26
diff[l] += k
diff[r + 1] -= k
# 还原前缀和,转回字符
for i in range(1, n + 1):
s[i] = diff[i] + s[i - 1]
print(chr(s[i] % 26 + 97), end='')
复杂度 :时间 O ( n + q ) O(n + q) O(n+q),空间 O ( n ) O(n) O(n)
例题 2:食堂 ⭐⭐⭐贪心分类讨论
| 项目 | 内容 |
|---|---|
| 链接 | https://www.lanqiao.cn/problems/19724/learning/ |
| 类型 | 贪心 + 分类讨论 |
| 核心 | 优先配对,能坐满就坐满,逐步降级处理 |
关键思路
贪心策略:大桌优先配大组合,逐步降级!
6人桌 :3+3 → 2+2+2 → 降级为4人桌
4人桌 :4 → 2+2 → 3 → 2
题解
python
q = int(input())
for _ in range(q):
a2, a3, a4, b4, b6 = map(int, input().split())
res = 0
# 6人桌:先3+3配对
d3 = a3 // 2
if b6 <= d3:
res += b6 * 6
a3 -= b6 * 2
else:
res += d3 * 6
a3 -= d3 * 2
b6 -= d3
b4 += b6
if a2 >= b6:
res += b6 * 2
a2 -= b6
else:
res += a2 * 2
a2 = 0
# 4人桌:4 → 2+2 → 3 → 2
if b4 > a4:
res += a4 * 4
b4 -= a4
d2 = a2 // 2
if b4 > d2:
res += d2 * 4
b4 -= d2
a2 -= d2 * 2
if b4 > a3:
res += a3 * 3
b4 -= a3
if a2 != 0:
res += 2
else:
res += b4 * 3
else:
res += b4 * 4
else:
res += b4 * 4
print(res)
复杂度 :时间 O ( q ) O(q) O(q),空间 O ( 1 ) O(1) O(1)
例题 3:X进制减法 ⭐⭐⭐大数运算
| 项目 | 内容 |
|---|---|
| 链接 | https://www.lanqiao.cn/problems/2108/learning/ |
| 类型 | 大数运算 + 进制转换 |
| 核心 | 从低位到高位,每位进制取最小,防止溢出 |
关键思路
A − B = ∑ ( a i − b i ) × x i A - B = \sum (a_i - b_i) \times x_i A−B=∑(ai−bi)×xi
要使 A − B A - B A−B 最小 :每位进制都取最小值 m a x ( a i + 1 , b i + 1 , 2 ) max(a_i+1, b_i+1, 2) max(ai+1,bi+1,2)
题解
python
Mod = 1000000007
N = int(input())
n1 = int(input())
num1 = list(map(int, input().split()))
n2 = int(input())
num2 = list(map(int, input().split()))
# 补齐B的位数
while len(num2) < n1:
num2 = [0] + num2
ans = 0
x = 1
# 从低位到高位遍历
for i in range(n1 - 1, -1, -1):
ans = (ans + (num1[i] - num2[i]) * x) % Mod
x = x * max(num1[i] + 1, num2[i] + 1, 2) % Mod
print(ans % Mod)
复杂度 :时间 O ( n ) O(n) O(n),空间 O ( n ) O(n) O(n)
例题 4:巧克力 ⭐⭐⭐⭐⭐ 贪心+优先队列
| 项目 | 内容 |
|---|---|
| 链接 | https://www.lanqiao.cn/problems/1596/learning/ |
| 类型 | 贪心 + 优先队列(小根堆) |
| 核心 | 从后往前贪心,每天选最便宜的可用巧克力 |
关键思路
为什么不能简单按价格排序?
反例:价格1(保质期10天,数量2)+ 价格3(保质期4天,数量3)+ 价格10(保质期5天,数量4)。简单排序会导致前面吃便宜的,后面不得不吃贵的。
正确策略:
- 按保质期从大到小排序
- 从最后一天往前遍历
- 维护小根堆,每天选最便宜的
题解
python
import heapq
x, n = map(int, input().split())
l = []
for i in range(n):
a, b, c = map(int, input().split())
l.append([a, b, c])
# 按保质期从大到小排序
l.sort(key=lambda pair: -pair[1])
res, j = 0, 0
q = []
# 从最后一天往前遍历
for i in range(x, 0, -1):
while j < n and l[j][1] >= i:
heapq.heappush(q, [l[j][0], l[j][1], l[j][2]])
j += 1
if not q:
print(-1)
break
t = heapq.heappop(q)
res += t[0]
t[2] -= 1
if t[2]:
heapq.heappush(q, t)
else:
print(res)
复杂度 :时间 O ( n log n + x log n ) O(n \log n + x \log n) O(nlogn+xlogn),空间 O ( n ) O(n) O(n)
例题 5:管道 ⭐⭐⭐⭐⭐ 二分+区间合并
| 项目 | 内容 |
|---|---|
| 链接 | https://www.lanqiao.cn/problems/3544/learning/ |
| 类型 | 二分查找 + 区间合并 |
| 核心 | 二分最小时间,检查该时间是否能覆盖整个管道 |
关键思路
二分答案 :时间 T T T 越大,水流扩散越远,具有单调性。
check(T):
- 计算每个阀门在 T T T 时刻覆盖的区间:
[Li-(T-Si), Li+(T-Si)] - 合并所有区间
- 检查是否覆盖
[1, Len]
题解
python
def check(Ti, values, Len):
section = []
for Li, Si in values:
if Ti >= Si:
spread = Ti - Si
section.append((Li - spread, Li + spread))
section.sort()
if not section or section[0][0] > 1:
return False
right_boundary = section[0][1]
for i in range(1, len(section)):
if section[i][0] - right_boundary <= 1:
right_boundary = max(right_boundary, section[i][1])
else:
break
return right_boundary >= Len
n, Len = map(int, input().split())
values = [list(map(int, input().split())) for _ in range(n)]
left, right = 0, 10 ** 9
while left < right:
mid = (left + right) // 2
if check(mid, values, Len):
right = mid
else:
left = mid + 1
print(left)
复杂度 :每次 check 为 O ( n log n ) O(n \log n) O(nlogn),二分 O ( log 10 9 ) O(\log 10^9) O(log109),总时间 O ( n log n log 10 9 ) O(n \log n \log 10^9) O(nlognlog109)
三、今日刷题总结
| 题号 | 题目 | 考点 | 难度 | 核心技巧 |
|---|---|---|---|---|
| 1 | 字符迁移 | 差分进阶 | ⭐⭐⭐ | 字符转数字,差分循环移位 |
| 2 | 食堂 | 贪心分类 | ⭐⭐⭐⭐ | 大桌优先配对,逐步降级 |
| 3 | X进制减法 | 大数运算 | ⭐⭐⭐⭐ | 从低位到高位,取最小进制 |
| 4 | 巧克力 | 贪心+堆 | ⭐⭐⭐⭐⭐ | 从后往前,小根堆选最小 |
| 5 | 管道 | 二分+区间合并 | ⭐⭐⭐⭐⭐ | 二分答案,检查区间覆盖 |
核心算法模板汇总
python
# ===== 模板1:差分处理循环移位 =====
for i in range(1, n+1):
s[i] = ord(s[i]) - 97
diff[i] = s[i] - s[i-1]
diff[l] += k; diff[r+1] -= k
for i in range(1, n+1):
s[i] = diff[i] + s[i-1]
print(chr(s[i] % 26 + 97), end='')
# ===== 模板2:贪心+优先队列(从后往前) =====
l.sort(key=lambda x: -x[1])
q = []
j = 0
for i in range(x, 0, -1):
while j < n and l[j][1] >= i:
heapq.heappush(q, l[j]); j += 1
t = heapq.heappop(q)
# 处理t...
# ===== 模板3:二分查找(找最小满足条件) =====
left, right = 0, max_val
while left < right:
mid = (left + right) // 2
if check(mid): right = mid
else: left = mid + 1
print(left)
# ===== 模板4:区间合并 =====
section.sort()
right_boundary = section[0][1]
for i in range(1, len(section)):
if section[i][0] - right_boundary <= 1:
right_boundary = max(right_boundary, section[i][1])
else: break
四、结语
今天的5道题都是蓝桥杯算法赛真题,难度直接对标国赛:
🌟 今日收获:
- 差分进阶:字符转数字处理循环移位,拓展了差分的应用场景
- 贪心策略:大桌优先配对、从后往前选最小,贪心无处不在
- 大数运算:X进制减法的取模技巧,防止溢出
- 优先队列:维护可用集合,动态选最优,是高级贪心的标配
- 二分答案:将最优化问题转化为判定问题,配合check函数
记住:看到区间修改想差分,看到最优化问题想贪心,看到"最小/最大满足条件"想二分!
继续加油,国赛见!💪
如果本文对你有帮助,欢迎 点赞 👍 + 收藏 ⭐ + 关注 🔔,你的支持是我持续更新的动力!