趣味数学编程题解之一场温和的赌博游戏

IT商界

  赌博虽然不是一项被社会提倡的活动,但和赌相联系的故事实在是太多了。小时候,我们和同龄的小伙伴为了一个问题也要赌一把。其实在赌的时候,除了聪明的头脑外,有趣的规则也是非常美妙的。下面的规则就有些意思,除了看美妙的规则外,我们还要思考一下如何让电脑来帮我们解决这个问题。

  题目:一场温和的赌博游戏

  阿东和阿西是两个美国小学生,一天,他们玩起了赌博游戏。“我没有1美分的零币,”阿东说着,一边“叮当”地敲着他的钱币,“你有多少?”   

  阿西查看了一下自己的口袋,回答道:“正好7枚。怎么啦?”   

  “我想我们来一次小小的赌博游戏怎么样?”阿东一边说一边开始分牌,“规定这样的:第一局输的人,输掉他钱的五分之一;第二局输的人,输掉他那时拥有的四分之一;而第三局输的人,则须支付他当时拥有的三分之一。”

  于是他们开始玩了,并且互相准确付了钱。第三局阿西输了,付完钱后他站起来声明说:“我觉得这种游戏投入的精力过多,回报太少。直到现在我们之间的钱数,总共也只相差7美分。”

  这自然是很小的赌博,因为他们合起来一共也只有75美分的赌本。   

  试问,在游戏开始的时候阿东有多少钱呢?

  赌局分析

  (1)阿东究竟有多少钱呢?

  在计算钱之前需先对美元硬币的情况做一下了解。目前美国流通的硬币有1美分、5美分、10美分、25美分、50美分和1美元。有了这个前提,我们可以大体猜测一下。因为阿东没有1美分的零币,所以最少是5美分了,也不可能全有,因为阿西有7枚,假设阿西手头全是1美分的,阿东最多是75-1×7=68美分。

  (2)赌局的可能情况是怎样的呢?

  按照时间顺序,总计三局,并且三局情况不一定一样。

  第三局是明确的了,可前两局不知胜负情况,前两局的胜负有四种可能,阿东全赢,阿西全赢,阿东第一局胜第二局负,阿东第一局负第二局胜。

  所以假设阿东是X,阿西自然是75-X,而中间有四种变化,不论哪一种情况只要最后能够出现二人相差7分钱,就说明这种方案是可选的。

  处理过程的分析

  有了上面的分析,我们编程也就有了依据。

  设阿东钱数为X,则X可从5到68,究竟哪一种是阿东的钱的情况呢?

  判断的条件是一连串的:必须对每一套方案按照四种可能的赌局加第三赌局的情况进行判断,如果符合条件,证明成立,否则不成立。

  “于是他们玩了,并且互相间准确付了钱”,这一句话必须给予足够重视。在赌局进行的过程中这是一个必须关注的问题,这个问题是我们容易忽略的,那就是双方付钱时不会出现小数,将这个条件变换一下即刚开始第一局负的一方的金钱的数量必须能够被5整除,第二局进行之前负的一方能够被4整除,第三局进行之前负的一方能被3整除。(我们分析到这里打住,往下分析,可能还有一个相互间找零能否实现的问题,这个问题在本题中我们将不再探讨,有兴趣你可自己解决一下。)

  有了第一局的过程,也有了总计多少局。问题就很简单了,我们利用X循环,在循环中将赌局的次序放上,并在玩完后加以判断,符合条件的自然就是我们想要的。

  N-S图的初始状况如图所示。图中的大部分还需要进行细化处理,处理过程可以自己补充完整。

  上图中用到一个多分支语句,其特点和if then分支差不多,只不过前者能解决更多的情况。在题中有四种情况,我们选择使用了多分支。由于每种情况都必须考虑到,所以在多分支语句的外面通过一个循环语句执行四次来将所有的情况都包括进去。

  语言、界面、源程序

  (1)语言

  程序中通过Visual BASIC6.0语言来实现。

  (2)界面

  界面非常简单,建立一标准EXE工程,caption设为“赌博游戏”。我们将代码加给Form_Click()即窗体的单击事件,将来运行时,我们只要用鼠标单击一下窗体,程序就执行了。

  (3)源程序

  从图中我们不难看到,程序的整体结构是循环,这个循环是针对阿东的钱数的。循环的内部是一个顺序语句和另外一个循环,前者用来计算阿西的钱数,后者则用来使可能的方案全部经过一遍。在最内循环的内部,则是一场按时间进行的赌局。从第一局到第三局是情况的模拟,模拟完情况后通过分支语句判断这一局是否符合条件,是否正是我们需要的赌局,如果是则输出。源程序如下:

  Option Explicit

  Private Sub Form_Click()

  Dim x, x1 As Integer '阿东的钱数

  Dim y, y1 As Integer '阿西的钱数

  dim x2 as integer'第二局负的一方在开局前的值

  dim x3 as integer'第三局负的一方在开局前的值

  Dim k, i, m As Integer

  '阿东的钱可能是5~68中的值

     For x = 5 To 68

     y = 75 - x

       For i = 1 To 4

        k = i

        x1 = x

        y1 = y

        '多分支语句

        Select Case k

        Case 1

        '阿东全胜    

        x1 = x1 + y1 / 5

        y1 = y1 * 4 / 5

        x2 = y1

        x1 = x1 + y / 4

        y1 = y1 * 3 / 4        

  Case 2

  '阿西全胜

  y1 = y1 + x1 / 5

  x1 = x1 * 4 / 5

  x2 = x1

  y1 = y1 + x1 / 4

  x1 = x1 * 3 / 4

  Case 3

  '阿东先胜后负

  x1 = x1 + y1 / 5

  y1 = y1 * 4 / 5

  x2 = x1

  y1 = y1 + x1 / 4

  x1 = x1 * 3 / 4

  Case Else

  '阿东先负后胜

  y1 = y1 + x1 / 5

  x1 = x1 * 4 / 5

  x2 = y1

  x1 = x1 + y1 / 4

  y1 = y1 * 3 / 4

  End Select

  '第三局阿西负

  x3 = y1

  x1 = x1 + y1 / 3

  y1 = y1 * 2 / 3

  '判断是否符合条件

  If Abs(x1 - y1) = 7 And (x Mod 5 = 0) And x2 Mod 4 = 0 And x3 Mod 3 = 0 Then

  m = i

  Select Case m

  Case 1

  Print "阿东:胜胜胜";

  Case 2

  Print "阿东:负负胜";

  Case 3

  Print "阿东:胜负胜";

  Case Else

  Print "阿东:负胜胜";

  End Select

  Print "阿东刚开始有:"; x;

  Print "阿西刚开始有:"; y

  End If

  Next i

  Next x

  End Sub

  (上程序在VB6.0、Win2000下调试通过)

  编程小结

  就这样,我们的小程就帮我们找出了阿东刚开始的钱数,整40美分。而阿东三个赌局的情况则是负、负、胜,阿西刚开始只有35美分。

  (1)条件多得有点烦

  上面的题目其实是不难的,但要做出来,还真要动一番脑筋,原因在哪里呢?条件特别多,在本题中,条件是时间上的一条线,必须在这条线上将各种条件理顺。所以如果条件很多,第一重要的是理清它们之间的脉络;在本题中,还有另外一种重要的条件,美元中硬币的常识,美元的面值和人民币不太一样。

  (2)理顺好条件,把握重点

  编程,有时就是怎样将各种方案全都模拟出来,不能忽略其中的重点问题。为了更加便于我们的分析,我们可以一层层地来考虑题目中的限定条件。可以先对最重要的进行分析,再对次要一点的,将它们作为限定条件放到程序中,看看最后的运行情况,往往我们需动半天脑筋结果才出得来。