趣味数学编程题解之奖金与女孩

IT商界

  平平淡淡才是真。生活中大部分的规律是普普通通的,面对这些规律,编起程来有点累人,但我们只要细心加耐心,解决起来应该没问题。

  下面的故事发生在一个办公室里。里面有个比较复杂的规律,找找吧?找出来问题也就解决了。

  发奖金对任何不是老板的人来说都是高兴的事情,可如何发有时却让老板比较为难。下面有一个故事,讲述了一位聪明老板如何发奖金。而我们的工作却是看看他的公司里究竟有几个女孩。

  题目:奖金和女孩

  当秘书走进办公室时,老板杰克微笑着说:“贝蒂,现在我事情已经做完,请把其他人都叫进来。”很快,包括贝蒂在内的5个职员都来到他跟前,他们不知出了什么事。但老板很快使他们轻松起来。杰克告诉他们:“我想你们一定很高兴知道,我在克莱蒙的交易最后赢利了,这里有一笔260美元的奖金,在你们之间分配意思一下。”

  贝蒂想自己职位较低,“也许轮不上我”这令人沮丧的念头刺伤了她的心。

  但令人满意的是,杰克继续说道:“我已经算出了你们跟着我工作的完整年限,并按这个比例发放奖金,但允许男人比女孩每年多得女孩的一半。”他一边说,一边递给每人一个信封。突发的情况,使雇员们显得有些局促不安。

  这对他们来说的确是一个好运气!

  已知他们工作的完整年限分别是2、3、5、6和7年。请你算出在杰克的职员中女性有几人?

  累人的规律

  看到这个题目,真有点让人摸不着头脑,原则是隐藏在其中的,那就是不要让每个人得到的钱太零碎,或者说,钱是整数,一共260美元,分的时候不要将一张钱扯成两半,有了这一最终原则,下面就可以分钱了。

  怎样分呢?还不能忽略另一原则,“男人比女孩每年多得女孩的一半”,为了更清楚地表述这种意思,我们可给男人和女孩不同的权值,男的是3,女的则是2。我们可将奖金分成相等的份数,2、3、5、6、7分别同2或3相乘然后求它们的和,比如,第一个人是男的,其他四人是女的,则奖金可分成2×3+3×2+5×2+6×2+7×2=48份,我们后面只要将第一人的2×3份再与260/48相乘,第二人的3×2也与260/48相乘……这样我们可得到5个数值,如果5个值都是整数,则证明就是这组合,我们可从中得出究竟有几个女孩。

  我们如何编程呢?编程,是从所有可能的男女组合中筛选出符合上述条件的方案来。

  可能的男女组合有哪些呢?

  (1)无女性,即5个男人,这种情况只有一种,同样的道理,5个女性的时候也是1种情况;

  (2)1女性,有5种情况,同样的道理,4个女性的时候也是5种情况,我们可将这种情况以1个男性来考虑。

  (3)2女性,有4+3+2+1种情况,同样的道理,3个女性的时候也是10种情况,我们可将这种情况以2个男性来考虑。

  而如何判断哪种方案合适呢?

  我们将上面的条件总结成一个,即看这个方案中各人的值(年数×3或2)和(260/方案的份数)相乘的积是否都是整数。如果5个都是,则证明正确,否则不正确。

  为了便于实现上述想法,可设两个数组a(1)-a(5)和aflag(1)-aflag(5),前者放工作年限,后者放性别的权值(2为女性,3为男性),这样设权值就实现了题中的一个条件:“男人比女孩每年多得一半”。

  有了上面的假设,各种不同的方案可通过调整aflag()的值来得到,源程序中给出了详细的说明。

  有了各种方案,下面可开始判断,判断通过一个子程序judge()来完成。

  界面和源程序

  (1)界面

  界面非常简洁,建立一标准EXE工程,在窗体中放入一个文本框负责输出,其名称为txtList,一个命令按钮cmdJudge,其caption属性为“判断”。

  (2)源程序

  Option Explicit '变量检查

  Dim a(1 To 5) As Integer '工作年限

  Dim aflag(1 To 5) As Integer '男女加权

  Sub judge() '判断子程序

  Dim i As Integer

  Dim k As Integer

  Dim m As Integer

  Dim s As Integer

  Dim flag As Integer '记录标志

  s = 0

  k = 0

  For i = 1 To 5

  If aflag(i) = 2 Then k = k + 1

  s = s + a(i)* aflag(i) 

  Next i

  flag = 0

  's = 260 / s

  For i = 1 To 5

  m = a(i)*aflag(i) * 260

  If m / s = Int(m / s) Then

  flag = flag + 1

  End If

  Next i

  If flag = 5 Then

  For i = 1 To 5

  If aflag(i) = 2 Then

  TxtList.Text = TxtList.Text + Str(a(i)) + "年" + "女性"

  Else

  TxtList.Text = TxtList.Text + Str(a(i))+ "年" + "男性"

  End If

  Next i

  'Print "人数为";k; 260 / s

  TxtList.Text = TxtList.Text + "女职员数:" + Str(k) + "符合条件人数:" + Str(260 / s) + vbCr + vbLf

  End If

  End Sub

  Private Sub CmdJudge_Click() '判断按钮

  Dim i, k, m As Integer

  TxtList.Text = ""

  '年限

  a(1) = 2

  a(2) = 3

  a(3) = 5

  a(4) = 6

  a(5) = 7

  '加权

  '5 女

  TxtList.Text = TxtList.Text + "5女" + vbCr + vbLf

  For i = 1 To 5

  aflag(i) = 2

  Next i

  '判断子程序

  Call judge

  '0女

  TxtList.Text = TxtList.Text + "0女" + vbCr + vbLf

  For i = 1 To 5

  aflag(i) = 3

  Next i

  '判断子程序

  Call judge

  '1男或4男

  TxtList.Text = TxtList.Text + "4女" + vbCr + vbLf

  For i = 1 To 5

  For k = 1 To 5

  If i = k Then

  aflag(k) = 3

  Else

  aflag(k) = 2

  End If

  Next k

  '判断子程序

  Call judge

  Next i

  TxtList.Text = TxtList.Text + "一女" + vbCr + vbLf

  For i = 1 To 5

  For k = 1 To 5

  If i = k Then

  aflag(k) = 2

  Else

  aflag(k) = 3

  End If

  Next k

  '判断子程序

  Call judge

  Next i

  '2女或3女

  TxtList.Text = TxtList.Text + "3女" + vbCr + vbLf

  For k = 1 To 5

  aflag(k) = 2

  Next k

  For i = 1 To 4

  afla(i) = 3

  For k = i + 1 To 5

  aflag(k) = 3

  For m = 1 To 5

  If m <> i And m <> k Then

  aflag(m) = 2

  End If

  Next m

  '判断子程序

  Call judge

  'For m = 1 To 5

  'aflag(m) = 2

  'Next m

  Next k

  Next i

  '初始化

  For k = 1 To 5

  aflag(k) = 3

  Next k

  TxtList.Text = TxtList.Text + "2女" + vbCr + vbLf

  For i = 1 To 4

  aflag(i) = 2

  For k = i + 1 To 5

  aflag(k) = 2

  For m = 1 To 5

  If m <> i And m <> k Then

  aflag(m)  = 3

  End If

  Next m

  '调用判断子程序

  Call judge

  'For m = 1 To 5

  '' aflag(m) = 3

  'Next m

  Next k

  Next i

  End Sub

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

  小结

  程序完成了,结果有两组:

  第一组:2年女性、3年女性、5年女性、6年男性、7年女性,女职员数:4;

  第二组: 2年男性、3年女性、5年男性、6年女性、7年男性,女职员数:2。