Scratch与数学的整合24
第24课 对策问题(二)
一、课程导入
1、比赛和游戏的对策多元化的,要各种因素全面地综合起来思考,不能仅停留在取胜概率上。例如取多堆数量不等的火柴时,我哪一次取多少根,才能把所有火柴全部取走?那么具体要学什么呢?我会在后面讲到。
二、教学目标
1、思维目标:能够灵活运用对策问题的本质解决该问题。
2、编程目标:利用Scratch列表用法、正负数的意义综合起来去编写与对策问题相关的Scratch作品。
三、例题讲解
1、已知有55个、46个、38个数量不等的三组小球。小红和小绿交替拿这些球。谁全拿走谁就获胜,每次拿走多少都可以,任意一组拿完才能拿剩下的任意一组。每组双方都要参与。问:“要小绿先取的话,小绿怎样去才能反败为胜”?
分析:首先看已知条件:已知有55个、46个、38个数量不等的三组小球。这句话说完就告诉了我们规则:小红和小绿交替拿这些球。谁全拿走谁就获胜,每次拿走多少都可以,任意一组拿完才能拿剩下的任意一组。每组双方都要参与。这种规则和上一课讲的例题差不多。∴这里我们可以挖掘出来一个隐藏条件:这种游戏属于“必输型”,先拿者输。不过问题问的是“绿怎样去才能反败为胜”。那么小明就要在劣势的状态下想办法如何扭转局面。第一组小绿和小红正常交替拿,第二组还是小绿和小红正常交替拿,这样等到第三组小绿无论取走多少个小球,小红都能一次性把剩下的小球全拿走,小红就反败为胜了。
2、已知哥哥有58个棋子,妹妹有68个棋子。双方交替取子,最多可以从一堆里全取走,但不能不取,也不能在自己把本方的棋子全取完之前取对方的棋子。谁取完谁获胜。证明:妹妹有反败为胜的可能。
分析:这道题人家没问我们谁如何取胜,而是让我么证明妹妹有反败为胜的可能。这里有隐藏条件,那我们就将概念关系与这几句话综合考虑进而挖出隐藏条件。“哥哥”和“妹妹”相同在于两人之间是对手,不同在于两词不同义,这样的概念关系属于交叉关系,那我们不难想出妹妹要防谁取胜呢?被动对象是谁呢?当然是先取的哥哥了。
证:∵哥哥有58个棋子,妹妹有68个棋子。双方交替取子,最多可以从一堆里全部拿走,但不能不取。因此妹妹必须先去玩自己比哥哥多的68-58=10(个)棋子,即妹妹第一次

可以任选1——10个棋子拿走。根据速战速决原则,妹妹可以第一次取10个棋子,接下来可以哥哥与妹妹交替取同一堆棋子,又交替取表示双方至少共取3次,那么哥哥第二次最多也只能取57个棋子,此时还剩58-57=1(个)棋子,且第三次妹妹取,∴最后一个棋子妹妹必然会去走,即此时妹妹把棋子全取完。得证。
四、探索新知
Scratch列表简介:
1、舞台区列表特征如图所示:

2、用法:
(1)将东西加入“东西”:在圆矩形内输入“东西”,系统会在列表上显示。
(2)删除东西的第1项:点击后列表的第1项没有了。
(3)删除东西的全部项目:清空列表。
(4)在东西的第1向前插入“1”:在列表第1项的前面再补上1个项目:“1”,“东西”就被“1”代替了。
(5)在东西的第1项替换为“东西”:点击后第1项原来的数据被新的数据代替,例如第1项原来是“2”,点击后“2”将会变成“东西”。
(6)东西的第1项:帮你查找第1项的数据是什么。
(7)东西中第1个“东西”的编号:帮你查找列表中最前面的那个“东西”在哪一项。
(8)东西的项目数:统计东西里的项目数
(9)显示列表东西:让你看见东西列表及其数据。隐藏列表东西反之同理。
五、流程图
1、我们先来看看用例1的解题过程来编写的程序所对应的流程图:

首先程序开始。先执行询问并回答3堆球的总数部分的流程,其中包括第一堆、第二堆、第三堆球的数量,每堆球的数量均重复1次,共3次,并将回答的语句依次加入到列表中。再询问:“第1回合双方取走哪堆?”将第1回合双方拿走的编号设为“回答”,同时删除列表中的“回答”项。接下来问:“第2回合双方取走哪堆?”该部分的“回答”、设的变量、项目删除同理于上一组(“剩下的球的个数”被替换为列表中的第一项除外)。再接下来问:“第3回合中先手拿走多少个球?”回答后判断该回答的数值是否在区间(0,剩下的球数)内,若在区间内则用剩下的求的个数减去第3回合中先手拿走的个数求出第3回合中后手拿走球的个数,并将“剩下的球的个数”的数据替换为“第3回合中后手拿走球的个数”的数据。对此数据进行回答:“此时后手取'第一项'个球一定能反败为胜”最后程序结束。
2、我们先来看看用例2的解题过程来编写的程序所对应的流程图:

首先程序开始。询问并回答甲、乙的棋子数,再对甲、乙的棋子数量做判断。若相等则代表“是”,并询问谁先取子,接下来若回答是甲,则得出答案:甲先取必输。若回答是乙,则得出答案:乙先取必输。若甲、乙的棋子数量不等则代表“否”,接下来比较甲、乙棋子数的多少。若判断为甲的棋子数更多,则代表“是”,再接下来用甲更多的棋子差减去乙更多的棋子差得出甲的棋子差,再接下来下一步将后续甲每次取的棋子数设为1到(甲更多的棋子差-1)的随机数,倒数第二步得出答案:甲能反败为胜。若乙的棋子更多则代表“否,再接下来用乙更多的棋子差减去甲更多的棋子差。再接下来下一步将后续乙每次取的棋子数设为1到(乙更多的棋子差-1)的随机数,倒数第二步得出答案:乙能反败为胜。最后程序结束。
六、变量与列表信息
在原作品中,角色“气球1”运行例题1编写的程序,角色“B”运行例题2编写的程序。与其对应用到的变量如下:
角色“气球1”运行的程序与其对应用到的变量:球的数量、第1回双方拿走的编号、第2回双方拿走的编号、剩下的球的个数、第3回合中先手拿走球的个数、第3回合中后手拿走球的个数

角色“B”运行的程序与其对应用到的变量:甲的棋子数、乙的棋子数、甲更多的棋子差、首次取出的棋子个数、后续甲每次取的棋子数、后续乙每次取的棋子数、乙更多的棋子差、先取者、必输方

角色“气球1”里建立的列表名为“球的数量”,操作过程如下:3个项目加入列表球的数量→先删除1项→再删除1项→得到第3回合中后手拿走球的个数




七、代码示例
1、“气球1”运行的程序对应的代码如下:
当绿旗被点击
∵是拿3组球,∴问3次:“有多少个球”,并将该回答加入列表球的数量
重复执行3次
询问有多少个球?
将球的数量设为回答
将球的数量加入球的数量
∵每组双方都要参与,又要求拿完一组才能拿下一组,这就说明无论怎样,都不用怕谁每组先抢完。反败为胜都是在劣势情况下逆转局面的,那这个过程必然是小红先取小绿赢。
询问第一回合拿走哪堆?
将第1回合拿走的堆号设为回答
删除球的数量的第回答项
询问第二回合拿走哪堆?
将第2回合双方拿走的堆号设为回答
删除球的数量的第回答项
列表中的数据3项删除后只剩下1项。此时是两人第3次取,整局开始既然是小绿取,那么此时小绿取走多少个,将由剩下的球的个数决定。
将剩下的球的个数设为球的第1项
询问第三回合中先手拿走多少个球
将第3回合中先手拿走球的个数设为回答
此时列表上显示的数字就是现在球剩的数量,而这恰好是第3回合中后手拿走的个数。得负数意味着不够拿,0意味着全那完了,不合题意,∴必须让“第3回合中后手拿球的个数”为正数,这时就用到了判断模块。
如果0<剩下球的个数<第3回合中先手拿走的个数那么
将第3回合中后手拿走球的个数设为:剩下的球的个数-第3回合中先手拿走球的个数
最后令列表上的编号为“第3回合中后手拿走球的个数”。
将球的数量的第1项替换为剩下的球的个数-第3回合中先手拿走球的个数
最后得出答案
说:“连接连接此时后手取和球的数量的第1项和1个球一定能反败为胜”

2、角色“B”运行的程序对应的代码如下:
当绿旗被点击 (0)
(1)——(4):首先确定甲、乙每方有多少堆棋子。
询问甲有多少堆棋子 (1)
将甲的棋子数设为回答 (2)
询问乙有多少堆棋子 (3)
将乙的棋子数设为回答 (4)

(5)——(20):这种游戏双方输赢的概率都相等,而前提是甲乙两方棋子数量相等,不相等就会有谁能反败为胜的概念,这就涉及到棋子差的问题,∴对甲乙两方棋子数量关系作比较,进而得出必输方或谁能反败为胜。
如果甲的棋子数=乙的棋子数不成立那么 (5)←第一层如果否则
如果甲的棋子数>乙的棋子数那么 (6)←第二层如果
将甲更多的棋子差设为:甲更多的棋子差-乙更多的棋子差 (7)
将首次取出棋子的个数设为:甲更多的棋子差 (8)
将后续甲每次取的棋子数设为在1和甲更多的棋子差-1之间取随机数 (9)
将后续乙每次取的棋子数设为:甲更多的棋子差-甲更多的棋子差 (10)
说:“最后甲能反败为胜” (11)
否则 (12)←内层的否则
询问谁先取子 (13)
将先取设设为回答 (14)
如果回答=甲那么 (15)←第三层上部分的如果
将必输方设为甲 (16)
说:“甲先取必输” (17)
如果回答=乙那么 (18)←第三层下部分的如果
将必输方设为乙 (19)
说:“乙先取必输” (20)


