[导读]:超平老师的Scratch蓝桥杯真题解读系列在推出之后,受到了广大老师和家长的好评,非常感谢各位的认可和厚爱。作为回馈,超平老师计划推出《Python蓝桥杯真题解析100讲》,这是解读系列的第79讲。
小朋友分糖果,本题是2022年3月13日举办的第13届蓝桥杯青少组Python编程选拔赛真题编程部分第4题。有N个小朋友从左到右排成一排,每个小朋友手中都有一定数量的糖果,且糖果总数量是N的倍数。 请编程计算出最少调整几次可以使每个小朋友的糖果数量相同。
先来看看题目的要求吧。
一.题目说明
编程实现:
有N个小朋友从左到右排成一排,每个小朋友手中都有一定数量的糖果,且糖果总数量是N的倍数。计算出最少调整几次可以使每个小朋友的糖果数量相同。
调整规则如下:
规则 1:每个小朋友的糖果只能调整到左右相邻的两个小朋友手中;
规则 2:第一个小朋友的糖果只能调整到第二个小朋友手中;
规则 3:最后一个小朋友的糖果,只能调整到倒数第二个小朋友手中。
例如:1~3 号小朋友原有糖果数量分别为6,4,2。
1)1号小朋友拿出两块给2号小朋友;
2)2号小朋友拿出两块给3号小朋友; 两次操作后三个小朋友手中糖果分别为 4,4,4。
即按照调整规则最少操作2次可以使3个小朋友手中糖果数量都相同。
现按照顺序给出1 ~ N号小朋友手中原有糖果数量,按照调整规则计算出最少调整几次可以使小朋友手中的糖果数量都相同。
输入描述:
输入N个正整数(1 < 正整数 < 100),表示1到N号小朋友手中原有糖果数量,正整数之间以一个英文逗号隔开,且所有正整数之和是N的倍数
输出描述:
按照调整规则计算出最少操作几次可以使小朋友手中糖果数量都相同
样例输入:
6,4,2
样例输出:
2
二.思路分析
这是一道算法题,涉及的知识点包括循环、条件、列表和模拟算法等。
糖果是每个小朋友都非常喜欢的零食,分糖果也是我们非常熟悉的场景。
对于本题中所描述的调整规则,如何保证调整次数最少呢,这其中又有什么规律和奥妙呢?
还是从实际案例入手吧,假设有5个小朋友,糖果数量分别为6, 4, 3, 1, 1,如图:
总糖果数量为15,平均下来,每个小朋友可以分得3颗糖果。
其调整过程如下:
看起来非常简单,都是从左边往右边调整,这是因为糖果数量是一个递减数列。
它有这么一个特点:处在左侧的小朋友糖果数量大于平均值,处在右侧的小朋友数量小于平均值。
所以,我们只需要从左到右依次调整,每一个小朋友只需要保留3颗糖果,其余的给到右边相邻的小朋友。
再调整一下顺序,如果5个小朋友的糖果数量依次是1, 1, 3, 4, 6,会是什么情况呢?
其实很简单,换个顺序,从右到左就可以了,如图所示:
继续调整顺序,如果5个小朋友的糖果数量是1, 3, 6, 1, 4呢,又该如何调整呢?
是从左到右,还是从右到左,亦或是从中间开始呢?
由于数据不具备单调性(递增或递减),无法通过一次从左到右或从右到左进行调整,需要分两次调整。
不妨先从左到右进行调整,由于第1个、第2个小朋友的糖果数量小于平均值3,因此保持不动。
第3个小朋友的糖果数量为6,需要调整,关键是向右调整多少颗呢?
有的同学可能会说3颗,自己保留3颗嘛。
不对,如果向右调整3颗的话,呆会儿还得调整回来,实际情况应该是右边缺多少,就调整多少。
右边还有两个小朋友,一共5颗糖果,还缺1颗,所以只需要向右调整1颗就行,如图所示:
然后再换个方向, 从右到左进行调整,规则还是一样的,左边缺多少就调整多少,如图所示:
从左到右调整了1次,从右到左又调整了3次,一共需要调整4次。
综合上述三种情况,我们可以统一处理,分两步:
1). 从左到右依次处理,如果当前糖果数量 > 平均值,则计算右边需要多少颗糖果并调整;
2). 从右到左依次处理,如果当前糖果数量 > 平均值,则计算左边还需要多少颗糖果并调整。
思路有了,接下来,我们就进入具体的编程实现环节。
三.编程实现
根据上面的思路分析,我们编写程序如下:
代码不少,强调三点:
1). 在遍历每一个小朋友的时候,都需要计算左侧和右侧需要的总糖果数量,直接使用列表的切片运算结合sum()函数即可;
2). 调整的条件有两个,一个是当前糖果数量 > 平均值,二是右侧或左侧还缺少糖果,二者缺一不可;
3). 糖果只能给到左边和右边相邻的小朋友,不能跳过。
至此,整个程序就全部完成了,你可以输入不同的数据来测试效果啦。
四.总结与思考
本题代码在20行左右,涉及到的知识点包括:
-
循环语句;
-
条件语句;
-
列表操作;
-
枚举算法;
本题代码不少,难度也较大,关键在于如何找到调整糖果的逻辑,我们可以通过举例法,找到其通用规律。
本题涉及到算法有两个,一是枚举算法,二是模拟算法。
枚举算法比较简单,就是使用循环把所有的情况都列举出来进行相应的处理。
模拟算法,就是利⽤计算机对⼀个过程进⾏模拟,并从中得出答案。比如,可以使用计算机模拟抛硬币得到正反面概率的情况,又比如模拟掷骰子、猜数字游戏等。
通常来说,模拟算法并没有固定的套路,具体问题需要具体分析。可以使用有代表性的数据来模拟解决问题的过程,找出其核心逻辑和通用规律。
你还有什么好的想法和创意吗,也非常欢迎和超平老师分享探讨。
如果你觉得文章对你有帮助,别忘了点赞和转发,予人玫瑰,手有余香😄
需要源码的,可以移步至“超平的编程课”gzh。