趣味数学编程题解之奖金与女孩
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。