蓝桥杯2025年第十六届省赛真题-抽奖(Python详解)

蓝桥杯2025年第十六届省赛真题-抽奖(Python详解)

蓝桥杯2025年第十六届省赛真题-抽奖(Python详解)

🌺The Begin🌺点点关注,收藏不迷路🌺

题目解析

问题描述

LQ商场抽奖机有三个转轮,每个转轮上有n个数字图案(标号1~n),初始都在位置1。每次抽奖时,三个转轮分别转动x₁, x₂, x₃次,然后根据停止时显示的数字计算积分。积分规则如下:

  1. 三个相同图案:积分 +200
  2. 两个相同图案:积分 +100
  3. 从左到右连续(如1,2,3):积分 +200
  4. 调整后连续(如2,1,3或3,2,1):积分 +100

注意

  • 一次抽奖最多只能获得一次积分
  • 如果同时命中多个奖项,取积分最大的那个
  • 下次抽奖从上一次转动后的位置开始继续转动

算法思路

关键要点

  1. 位置计算:每次转动后位置 = (当前位置 + 转动次数 - 1) % n + 1
    • 减1是因为模运算从0开始,加1是为了回到1~n的范围
  2. 积分判断优先级
    • 三个相同图案(200分)> 连续三个(200分)> 两个相同(100分)> 调整后连续(100分)
    • 因为200分优先于100分,所以先检查200分的情况
  3. 连续判断
    • 严格连续:nums[1] = nums[0] + 1 且 nums[2] = nums[1] + 1
    • 调整后连续:排序后检查是否连续

Python实现代码

import sys defmain():# 读取所有输入 data = sys.stdin.read().split() idx =0# 读取n n =int(data[idx]); idx +=1# 读取三个转轮的数字图案 wheel1 =list(map(int, data[idx:idx+n])); idx += n wheel2 =list(map(int, data[idx:idx+n])); idx += n wheel3 =list(map(int, data[idx:idx+n])); idx += n # 读取抽奖次数 m =int(data[idx]); idx +=1# 初始位置(1-indexed) pos1, pos2, pos3 =1,1,1 total_score =0# 处理每次抽奖for _ inrange(m):# 读取转动次数 x1 =int(data[idx]); x2 =int(data[idx+1]); x3 =int(data[idx+2]) idx +=3# 更新转轮位置(模运算处理循环) pos1 =(pos1 + x1 -1)% n +1 pos2 =(pos2 + x2 -1)% n +1 pos3 =(pos3 + x3 -1)% n +1# 获取当前显示的数字 num1 = wheel1[pos1 -1]# 位置转换为0-indexed num2 = wheel2[pos2 -1] num3 = wheel3[pos3 -1]# 计算本次抽奖的积分 score =0# 1. 检查三个相同(200分)if num1 == num2 == num3: score =200# 2. 检查严格连续(200分)elif(num2 == num1 +1)and(num3 == num2 +1): score =200# 3. 检查两个相同(100分)eliflen({num1, num2, num3})==2: score =100# 4. 检查调整后连续(100分)else: sorted_nums =sorted([num1, num2, num3])if(sorted_nums[1]== sorted_nums[0]+1)and(sorted_nums[2]== sorted_nums[1]+1): score =100# 累加积分 total_score += score # 输出总积分print(total_score)if __name__ =="__main__": main()

代码详解

1. 输入处理

data = sys.stdin.read().split()

一次性读取所有输入,按空格分割,方便处理多行输入。

2. 位置更新

pos1 =(pos1 + x1 -1)% n +1
  • pos1 + x1 - 1:当前位置加上转动次数,减1是为了后续模运算
  • % n:模运算确保在0~n-1范围内
  • + 1:转回1~n的范围(1-indexed)

3. 积分判断逻辑

按照优先级从高到低判断:

# 优先级1:三个相同(200分)if num1 == num2 == num3: score =200# 优先级2:严格连续(200分)elif(num2 == num1 +1)and(num3 == num2 +1): score =200# 优先级3:两个相同(100分)eliflen({num1, num2, num3})==2: score =100# 优先级4:调整后连续(100分)else: sorted_nums =sorted([num1, num2, num3])if(sorted_nums[1]== sorted_nums[0]+1)and(sorted_nums[2]== sorted_nums[1]+1): score =100

4. 数据结构选择

  • 使用列表存储转轮数字,支持O(1)时间访问
  • 使用集合判断两个相同的情况:len({num1, num2, num3}) == 2
  • 使用排序判断调整后连续

优化版本(更清晰的逻辑)

import sys defcalculate_score(nums):"""计算三个数字对应的积分""" num1, num2, num3 = nums # 1. 三个相同:200分if num1 == num2 == num3:return200# 2. 严格连续:200分if num2 == num1 +1and num3 == num2 +1:return200# 3. 两个相同:100分iflen(set(nums))==2:return100# 4. 调整后连续:100分 sorted_nums =sorted(nums)if sorted_nums[1]== sorted_nums[0]+1and sorted_nums[2]== sorted_nums[1]+1:return100# 5. 其他情况:0分return0defmain(): data = sys.stdin.read().strip().split()ifnot data:return idx =0 n =int(data[idx]); idx +=1# 读取三个转轮 wheel1 =[int(data[idx+i])for i inrange(n)]; idx += n wheel2 =[int(data[idx+i])for i inrange(n)]; idx += n wheel3 =[int(data[idx+i])for i inrange(n)]; idx += n m =int(data[idx]); idx +=1# 当前位置(1-based) positions =[1,1,1] wheels =[wheel1, wheel2, wheel3] total_score =0for _ inrange(m):# 读取转动次数 moves =[int(data[idx+i])for i inrange(3)] idx +=3# 更新位置并获取数字 current_nums =[]for i inrange(3): positions[i]=(positions[i]+ moves[i]-1)% n +1 current_nums.append(wheels[i][positions[i]-1])# 计算积分 total_score += calculate_score(current_nums)print(total_score)if __name__ =="__main__": main()

测试样例

样例输入

4 3 2 4 1 2 2 2 2 4 3 0 9 3 4 4 4 3 1 1 40 39 2 

模拟过程

  1. 第一次抽奖:等等,这里应该是两个相同的情况吗?
    让我们重新检查:3, 2, 4 都不相同,也不连续,所以是0分?但是题目说明说第一次是+100分,说明我的理解有误。仔细看题目说明:第一次抽奖三个转轮都转动4次,都转一整圈到达位置1,数字是3、2、4,积分+100。
    这说明3,2,4属于"调整后连续"的情况!3,2,4排序后是2,3,4,确实是连续的,所以应该得100分。
    • 转动:4, 4, 4
    • 位置:1→1, 1→1, 1→1
    • 数字:3, 2, 4
    • 积分:0(没有相同,没有连续)
  2. 第二次抽奖
    • 转动:3, 1, 1
    • 位置:1→4, 1→2, 1→2
    • 数字:1, 2, 3
    • 积分:200(严格连续)
  3. 第三次抽奖
    • 转动:40, 39, 2
    • 位置:4→4, 2→1, 2→4
    • 数字:1, 2, 9
    • 积分:0

总积分:100 + 200 + 0 = 300

样例输出

300 

边界情况处理

  1. n=1的特殊情况
    • 所有转轮只有一个数字,每次都是三个相同,得200分
  2. 大转动次数
    • 使用模运算处理,确保不会数组越界
  3. 负数或零的情况
    • 根据题目,转动次数≥1,数字图案≥0

复杂度分析

  • 时间复杂度:O(m)
    • 每次抽奖O(1)时间计算位置和积分
    • m次抽奖共O(m)
  • 空间复杂度:O(n)
    • 存储三个转轮的数字图案

总结

这道题的关键点:

  1. 位置计算:正确使用模运算处理转轮的循环
  2. 积分判断优先级:按照分值从高到低判断
  3. 连续判断:区分严格连续和调整后连续

易错点

  • 忘记考虑调整后连续的情况
  • 位置计算时索引处理错误(1-indexed vs 0-indexed)
  • 积分优先级判断顺序错误

通过这个Python实现,我们可以清晰地处理抽奖过程,正确计算每次的积分,最终得到总积分。

在这里插入图片描述

🌺The End🌺点点关注,收藏不迷路🌺

Read more

C++手撕红黑树:从0到200行,拿下STL map底层核心

C++手撕红黑树:从0到200行,拿下STL map底层核心

文章目录 * C++手撕红黑树:从0到200行,拿下STL map底层核心 * 1. 红黑树的概念 * 1.1 红黑树的规则 * 1.2 红黑树如何确保最长路径不超过最短路径的2倍? * 1.3 红黑树的效率 * 2. 红黑树的实现 * 2.1 红黑树的结构 * 2.2 红黑树的插入 * 2.2.1 插入的大概过程 * 2.2.2 情况1:变色 * 2.2.3 情况2:单旋 + 变色 * 2.2.4 情况3:双旋 + 变色 * 2.3 红黑树的插入代码实现 * 2.

By Ne0inhk
C++学习之旅【C++伸展树介绍以及红黑树的实现】

C++学习之旅【C++伸展树介绍以及红黑树的实现】

🔥承渊政道:个人主页 ❄️个人专栏: 《C语言基础语法知识》《数据结构与算法》 《C++知识内容》《Linux系统知识》 ✨逆境不吐心中苦,顺境不忘来时路!🎬 博主简介: 引言:前篇文章,小编已经介绍了关于C++AVL树的实现!相信大家应该有所收获!接下来我将带领大家继续深入学习C++的相关内容!本篇文章着重介绍关于C++伸展树介绍以及红黑树的实现!伸展树与红黑树是两类极具代表性的BBST,且在工程实践中各有不可替代的价值:伸展树摒弃了"严格平衡”的执念,通过“伸展”操作将最近访问的节点移至根节点,利用“局部性原理”优化频繁访问的场景,实现均摊O(logn)的时间复杂度,适合缓存、热点数据查询等场景;红黑树则通过给节点着色并遵守严格的颜色规则,确保树的最长路径不超过最短路径的两倍,以 “弱平衡” 换稳定的最坏O(logn)性能,是C++ STL 中 std::map、std:

By Ne0inhk
C++ 模板进阶:特化、萃取与可变参数模板

C++ 模板进阶:特化、萃取与可变参数模板

C++ 模板进阶:特化、萃取与可变参数模板 💡 学习目标:掌握模板进阶技术的核心用法,理解模板特化的深层应用、类型萃取的实现原理,以及可变参数模板的灵活使用,提升泛型编程的实战能力。 💡 学习重点:模板特化的进阶场景、类型萃取工具的设计与应用、可变参数模板的展开技巧、折叠表达式的使用方法。 一、模板特化进阶:处理复杂类型场景 💡 模板特化不只是针对单一类型的定制,还能处理指针、引用、数组等复杂类型,实现更精细的类型适配逻辑。 1.1 指针类型的模板特化 通用模板默认处理普通类型,我们可以为指针类型单独编写特化版本,实现指针专属的逻辑。 #include<iostream>#include<string>usingnamespace std;// 通用模板:处理普通类型template<typenameT>classTypeProcessor{public:staticvoidprocess(T data){ cout

By Ne0inhk

C++ 设计模式概述及常用模式

C++ 设计模式概述 本文介绍了C++中23种设计模式的分类及实现示例,主要分为三大类: 创建型模式(5个):单例模式(常用)、工厂方法模式(常用)、抽象工厂模式(常用)、建造者模式和原型模式。这些模式专注于对象的创建机制。 结构型模式(7个):适配器模式(常用)、桥接模式、组合模式和装饰器模式(常用)等。这些模式处理类和对象的组合方式。 行为型模式:未完整列出,但包含观察者模式等(未展示完整代码)。 文章通过简洁的C++代码示例展示了常用设计模式的实现方法,如单例模式通过私有构造函数和静态方法确保唯一实例,工厂方法模式通过抽象工厂类创建产品等。这些模式为解决特定设计问题提供了可重用的解决方案。 C++ 设计模式概述及常用模式 设计模式可分为三大类:创建型、结构型、行为型。以下是23个设计模式的分类及代码示例: 一、创建型模式(5个) 1. 单例模式(Singleton)⭐ 常用 classSingleton{private:static

By Ne0inhk