爱因斯坦的难题 VB 解
作者:赵玉勇
传说下面是爱因斯坦出的一道测试题。他说世界上有 99%的人回答不出这道题,看看你是否
属于另外的 1%?题目如下:
前提:
1 有五栋五种颜色的房子
2 每一位房子的主人国籍都不同
3 这五个人每人只喝一种饮料,只抽一种牌子的香烟,只养一种宠物
4 没有人有相同的宠物,抽相同牌子的香烟,喝相同的饮料
重要提示:
1 英国人住在红房子里
2 瑞典人养了一条狗
3 丹麦人喝茶
4 绿房子在白房子左边
5 绿房子主人喝咖啡
6 抽 PALL MALL 烟的人养了一只鸟
7 黄房子主人抽 DUNHILL 烟
8 住在中间那间房子的人喝牛奶
9 挪威人住第一间房子
10 抽混合烟的人住在养猫人的旁边
11 养马人住在 DUNHILL 烟的人旁边
12 抽 BLUE MASTER 烟的人喝啤酒
13 德国人抽 PRINCE 烟
14 挪威人住在蓝房子旁边
15 抽混合烟的人的邻居喝矿泉水
问题是:
谁养鱼?
我们可以拿出纸笔来,经过一番写写划划,然后动脑筋,做出来也可能做不出来。其实这个
问题的另一个重要意义是,这是个非常酷的编程素材。对这个问题进行编程,不仅仅可开动
您的脑盘,还可考考电脑的运算速度。OK,下面我们来共同做一下。
让电脑来做这个题。无非是在众多的备选方案中通过题中的 4 个前题加 15 个提示总计 19 个
条件来进行判断,找出那一个或多个可能的方案来。但是我们稍微做一下计算机,象又不敢
完全这么做,总计有多少种可能呢?
五种国籍,五种饮品,五种宠物,五种房色,五种香烟并且总计五个人,所有的方案有
5X5X5...X5,总计是 25 个五相乘,那是个非常大的数:300,000,000,000,000,000,大约这
么大。
一、数组和循环
所以我们最好的办法还是用条件来限制一下,使备选方案尽可能少一点。下面我们就来实现
我们的想法。
怎样将众多的方案一种一种的描述呢?那当然要用循环语句了,可题中的条件都是字符,不
能直接来循环,我们最好利用数组来完成这个艰巨的任务了。
我们定义了五个数组来放置已知的各种条件:
Dim country(1 To 5) As String '国籍
Dim color(1 To 5) As String '房间色
Dim drink(1 To 5) As String '饮料
Dim animal(1 To 5) As String '宠物
Dim tobaco(1 To 5) As String '烟
综合情况则放在下面的数组中,
Dim ration(1 To 25) As String '综合情况记录
ration(1)用来表示第一个人的国籍,2 用来表示房间色,3 表示饮料,4 表示宠物,5 表示
烟,6-10 表示第二人对应的各种东东,第三个人的自然就放在 11-15,第四第五以次类推。
有了这个数组,将来我们可以输出谁养鱼,也可以将各种方案循环表示出来。
有了上面的数组,所有的方案也就出来了,首先对 ration(1)循环取五个国籍值,内嵌对
ration(6)取五个国籍,ration(11),ration(16),ration(21),所以,五个嵌套的循环有了,
国籍的各种情况也就表达出来了。
其次可对 ration(2)循环取五个房间色值,内嵌对 ration(7)取五个房间色,
ration(12),ration(17),ration(22),所以,五个嵌套的循环有了,颜色的各种情况也就表
达出来了。这五个循环嵌在上面五个循环中,关于国籍,颜色的各种方案就都有了。
其他的对饮料,对宠物和烟的方法与此相类。一共 25 重循环就有了。因为这样计算机量将
非常庞大,我们再考虑利用题中的条件将循环减化。
首先综合通读题中的 4 个前题,我们可对循环进行限定,因为五个人每人只喝一种饮料,只
抽一种牌子的香烟,只养一种宠物,没有人有相同的宠物,香烟,饮料,国籍和房色,例如
国籍的循环,事实上在对取第一个房间的值时可任选,但取第二个时第一个国籍将不能取,
同理,第三个取值时不能取前两个,第四个不能取前三个,而最后一个只能取剩下的那一个
了。
其次,有一些条件已是确定的了,例如提示 8 住在中间那间房子的人喝牛奶,我们只要将此
条件用上就行了,不必再循环或选择了。也即 ration(13)="牛奶"。提示 9 和 14 也可完全
用这种方式表达。所以通过这三个提示,就减少了三个循环,可不要小瞧,这就将运行整度
提高了大约 100 倍!
再者就是综合前两点和 15 个提示,我们没愉要全部二十五个循环都用上,只要选择国籍,
颜色和饮料三个就可以了,而三者加起来也只有区区十二个循环,详细程序如下:
'饮品
ration(13) = drink(5)
For i21 = 1 To 4
ration(3) = drink(i21)
For i22 = 1 To 4
If i22 <> i21 Then
ration(8) = drink(i22)
For i23 = 1 To 4
If (i23 = i22) Or (i23 = i21) Then
Else
ration(18) = drink(i23)
For i24 = 1 To 4
If (i24 = i21) Or (i24 = i22) Or (i24 = i23) Then
Else
ration(23) = drink(i24)
'国籍
ration(1) = country(1)
For i2 = 2 To 5
ration(6) = country(i2)
For i3 = 2 To 5
If i3 = i2 Then
Else
ration(11) = country(i3)
For i4 = 2 To 5
If i4 = i2 Or i4 = i3 Then
Else
ration(16) = country(i4)
For i5 = 2 To 5
If i5 = i2 Or i5 = i3 Or i5 = i4 Then
Else
ration(21) = country(i5)
'房色
i7 = 4
For i6 = 1 To 5
If i7 <> i6 Then
ration(2) = color(i6)
ration(7) = color(i7)
For i8 = 1 To 5
If i8 = i6 Or i8 = i7 Then
Else
ration(12) = color(i8)
For i9 = 1 To 5
If i9 = i6 Or i9
= i7 Or i9 = i8 Then
Else
ration(17)
= color(i9)
For i10
= 1 To 5
If
i10 = i6 Or i10 = i7 Or i10 = i8 Or i10 = i9 Then
Else
ration(22) = color(i10)
'调用判断输出子程序
Call feek
En
d If
'清
空
Fo
r i11 = 3 To 23 Step 5
ration(i11 + 1) = ""
ration(i11 + 2) = ""
Ne
xt i11
Next i10
End If
Next i9
End If
Next i8
End If
Next i6
'房色
'-------------
End If
Next i5
End If
Next i4
End If
Next i3
Next i2
'国籍
'---------
End If
Next i24
End If
Next i23
End If
Next i22
Next i21
'饮品
我们只要再用其他的 12 个提示条件对循环的方案进行过滤,最后正确的答案就出来了,12
个条件主要通过 feek()子程序来完成。
二、其他条件限定和输出
其他的 12 个条件在子程序 feek()中,输出也是在 feek()中,将 12 个条件都符合后才能进行
下面的输出,如果有一个条件不符,将从该条件退出子程序。在塑造条件时要和我们对
ration()数组的定义相关,其各个值的对应关系,及国籍、颜色、饮料、宠物和烟与其相邻
的东东的数值关系,这是我们描述相似的基础。
最后的输出因为方案不可能有很多,我们通过 TextBox 文本框控件来完成的。
Sub feek()
Dim k1, k2, k3, k4, k5, k6, k7, i11 As Integer
Dim flagcolor1, flagcolor2 As Integer
'下面三个条件在循环中已体现出来。
'9 挪威人住第一间房子
'14 挪威人住在蓝房子旁边
'8 住在中间那间房子的人喝牛奶
'1 英国人住在红房子里
If (ration(11) = "英国" And ration(12) = "红") Or (ration(16) = "英国" And ration(17)
= "红") Or (ration(21) = "英国" And ration(22) = "红") Then
Else
Exit Sub
End If
'4 绿房子在白房子左边
For k2 = 1 To 25
If ration(k2) = "绿" Then
flagcolor1 = k2
评论0