蓝桥杯2025年第十六届省赛真题-抽奖(Python详解)
蓝桥杯2025年第十六届省赛真题-抽奖(Python详解)
🌺The Begin🌺点点关注,收藏不迷路🌺 |
题目解析
问题描述
LQ商场抽奖机有三个转轮,每个转轮上有n个数字图案(标号1~n),初始都在位置1。每次抽奖时,三个转轮分别转动x₁, x₂, x₃次,然后根据停止时显示的数字计算积分。积分规则如下:
- 三个相同图案:积分 +200
- 两个相同图案:积分 +100
- 从左到右连续(如1,2,3):积分 +200
- 调整后连续(如2,1,3或3,2,1):积分 +100
注意:
- 一次抽奖最多只能获得一次积分
- 如果同时命中多个奖项,取积分最大的那个
- 下次抽奖从上一次转动后的位置开始继续转动
算法思路
关键要点
- 位置计算:每次转动后位置 = (当前位置 + 转动次数 - 1) % n + 1
- 减1是因为模运算从0开始,加1是为了回到1~n的范围
- 积分判断优先级:
- 三个相同图案(200分)> 连续三个(200分)> 两个相同(100分)> 调整后连续(100分)
- 因为200分优先于100分,所以先检查200分的情况
- 连续判断:
- 严格连续: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 +1pos1 + 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 =1004. 数据结构选择
- 使用列表存储转轮数字,支持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 模拟过程
- 第一次抽奖:等等,这里应该是两个相同的情况吗?
让我们重新检查: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(没有相同,没有连续)
- 第二次抽奖:
- 转动:3, 1, 1
- 位置:1→4, 1→2, 1→2
- 数字:1, 2, 3
- 积分:200(严格连续)
- 第三次抽奖:
- 转动:40, 39, 2
- 位置:4→4, 2→1, 2→4
- 数字:1, 2, 9
- 积分:0
总积分:100 + 200 + 0 = 300
样例输出
300 边界情况处理
- n=1的特殊情况:
- 所有转轮只有一个数字,每次都是三个相同,得200分
- 大转动次数:
- 使用模运算处理,确保不会数组越界
- 负数或零的情况:
- 根据题目,转动次数≥1,数字图案≥0
复杂度分析
- 时间复杂度:O(m)
- 每次抽奖O(1)时间计算位置和积分
- m次抽奖共O(m)
- 空间复杂度:O(n)
- 存储三个转轮的数字图案
总结
这道题的关键点:
- 位置计算:正确使用模运算处理转轮的循环
- 积分判断优先级:按照分值从高到低判断
- 连续判断:区分严格连续和调整后连续
易错点:
- 忘记考虑调整后连续的情况
- 位置计算时索引处理错误(1-indexed vs 0-indexed)
- 积分优先级判断顺序错误
通过这个Python实现,我们可以清晰地处理抽奖过程,正确计算每次的积分,最终得到总积分。
🌺The End🌺点点关注,收藏不迷路🌺 |