VB编程系列(5):农夫过河

问题描述:

一个农夫带了一只狼、一只羊和一颗白菜来到甲岸,他要把这三样东西东用船从甲岸带到乙岸,但这艘船只能容下农夫本人和另外一样东东。如果农夫不在场的话,狼会吃掉羊,羊会吃掉白菜。请编程为农夫解决这个过河问题。


解题思路:

第一次看到这类问题时,我蒙圈了——这就是个文字推理题,也能用编程来解决?细想之后,明白!只要能用数字表示,就能用程序来处理。

要确保三样东东都能过河,就必须使得农夫不在河岸的时候,甲岸和乙岸要么羊也不在,要么只有一样在,要么全都不在。

那要如何做判断呢?可以用 1 表示菜,2 表示狼,4 表示羊,这样,当羊不在时,三者之和小于 4,当只有一样在时,三者之和最大为 4,全都不在则和为 0,也就是说,只要三者之和不超过 4,则乘船方法可行。

另外,刚过河的东东不应该让它立即再回来,否则过河就没有意义了。

从甲岸去乙岸可以按羊、狼、菜、无的顺序来抉择,从乙岸回甲岸则可以按无、菜、狼、羊的顺序来抉择。


程序实现:

Dim AA(99), BB(99) As Integer  ' AA、BB分别存放从甲岸到乙岸和乙岸到甲岸跟农夫一起过河的东东
For i = 1 To 99
  AA(i) = -1
  BB(i) = -1
Next
A = Array(0, 1, 2, 4)  ' A存放在甲岸的代表各东东的数,0无,1菜,2狼,4羊
B = Array(0, 0, 0, 0)  ' B存放在乙岸的代表各东东的数
DIsp = Array("独自", "与菜一起", "与狼一起", "", "与羊一起")
ship = 0
k1 = 0
k2 = 0
Do While True
  For i = 3 To 0 Step -1
    If (A(i) <> ship) And (A(1) + A(2) + A(3) - A(i)) <= 4 Then
      ship = A(i)
      A(i) = 0
      B(i) = ship
      k1 = k1 + 1
      AA(k1) = ship
      Exit For
    End If
  Next
  For i = 0 To 3
    If (B(i) <> ship) And (B(1) + B(2) + B(3) - B(i)) <= 4 Then
      ship = B(i)
      B(i) = 0
      A(i) = ship
      k2 = k2 + 1
      BB(k2) = ship
      Exit For
    End If
  Next
  If A(1) + A(2) + A(3) = 0 Then Exit Do
Loop
For i = 1 To 99
  If AA(i) = -1 Then Exit For
  Print "农夫" & DIsp(AA(i)) & "从甲岸乘船到乙岸"
  If BB(i) = -1 Then Exit For
  Print "农夫" & DIsp(BB(i)) & "从乙岸乘船到甲岸"
Next


后记:

程序本身不够健壮,这是问题之一,本题有两个答案,但本程序只能给出一个答案,这是问题之二。可以用广度(或深度)优先搜索之法遍历出所有过河方法,但在 VB 中我实在不知道有怎样的数据结构可用。但程序设计语言各有各的特性,我还是愿意择其善者而从之。


附 Python 代码:

# -*- coding: cp936 -*-

AA = []
BB = []
A = [0, 1, 2, 4]
B = [0, 0, 0, 0]
Disp = ('独自', '与菜一起', '与狼一起', '',  '与羊一起')
ship = 0

while True:
    for k, j in enumerate(A[-1: : -1]):
        i = 3 - k
        if j != ship and A[1] + A[2] + A[3] - j <= 4:
            ship = j
            A[i] = 0
            B[i] = ship
            AA += [ship]
            break
    for i, j in enumerate(B):
        if j != ship and B[1] + B[2] + B[3] - j <= 4:
            ship = j
            B[i] = 0
            A[i] = ship
            BB += [ship]
            break
    if A[1] + A[2] + A[3] == 0:
        break

for i in range(max(len(AA), len(BB))):
    if i < len(AA):
        print '农夫%s从甲岸乘船到乙岸' %Disp[AA[i]]
    if i < len(BB):
        print '农夫%s从乙岸乘船到甲岸' %Disp[BB[i]] 

猜你喜欢

转载自blog.csdn.net/qq_37183108/article/details/80647757