备战蓝桥杯国赛【Day 12】

📌 写在前面 :今天的题目全部来自蓝桥杯算法赛真题 ,难度直接对标国赛!涵盖了差分数组进阶应用贪心策略二分查找优先队列大数运算等核心考点。这些题目不仅是国赛的高频考点,更是区分省一和国一的关键分水岭!


📚 今日刷题清单

题号 题目 类型 难度 核心考点
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 位(循环)。

关键思路

将字符问题转化为数字问题

  1. 字符转数字:'a' -> 0, 'b' -> 1, ..., 'z' -> 25
  2. 差分数组处理区间加法(对26取模)
  3. 还原前缀和,数字转回字符
推演验证
复制代码
输入: 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+32+2+2 → 降级为4人桌
4人桌42+232

题解
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)。简单排序会导致前面吃便宜的,后面不得不吃贵的。

正确策略

  1. 按保质期从大到小排序
  2. 最后一天往前遍历
  3. 维护小根堆,每天选最便宜的
题解
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)

  1. 计算每个阀门在 T T T 时刻覆盖的区间:[Li-(T-Si), Li+(T-Si)]
  2. 合并所有区间
  3. 检查是否覆盖 [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道题都是蓝桥杯算法赛真题,难度直接对标国赛:

🌟 今日收获

  1. 差分进阶:字符转数字处理循环移位,拓展了差分的应用场景
  2. 贪心策略:大桌优先配对、从后往前选最小,贪心无处不在
  3. 大数运算:X进制减法的取模技巧,防止溢出
  4. 优先队列:维护可用集合,动态选最优,是高级贪心的标配
  5. 二分答案:将最优化问题转化为判定问题,配合check函数

记住:看到区间修改想差分,看到最优化问题想贪心,看到"最小/最大满足条件"想二分

继续加油,国赛见!💪


如果本文对你有帮助,欢迎 点赞 👍 + 收藏 ⭐ + 关注 🔔,你的支持是我持续更新的动力!

相关推荐
Cloud_Shy6181 小时前
Python 数据分析基础入门:《Excel Python:飞速搞定数据分析与处理》学习笔记系列(第八章 使用读写包操作 Excel 文件 下篇)
python·数据分析·excel·numpy·pandas
tryCbest1 小时前
Flask vs FastAPI 全方位对比与实战
python·flask·fastapi
测试员周周1 小时前
【Appium 系列】第04节-Page Object 模式 — BasePage 基类设计
开发语言·数据库·人工智能·python·语言模型·appium·web app
无限中终1 小时前
如何抓取某音视频的互动数据
爬虫·python
坐吃山猪1 小时前
Python34_装饰器知识
开发语言·python·ubuntu
ZHW_AI课题组1 小时前
调用华为智能云API实现手写图片识别
图像处理·python·机器学习·华为·分类
weixin_660096781 小时前
【无标题】
python·debugpy
小草cys1 小时前
Anaconda 的虚拟环境(envs)从默认的 C 盘迁移到其他磁盘
开发语言·python·anaconda
keineahnung23451 小时前
PyTorch SymNode 的 _is_contiguous 從何而來?──sizes_strides_impl 實作詳解
人工智能·pytorch·python·深度学习