問題描述
農夫(Human)過河。一個農夫帶着一隻狼(Wolf),一隻羊(Sheep)和一些菜(Vegetable)過河。河邊只有一條船,由於船太小,只能裝下農夫和他的一樣東西。在無人看管的情況下,狼要吃羊,羊要吃菜,請問農夫如何才能使三樣東西平安過河?
要求:
輸出一行,爲最終的過河方式,方案格式爲 過河人員、回來人員、過河人員、回來人員、…、過河人員。
過去和回來的人員之間,用空格隔開。
以四個生物英文的首字母代指對應的生物(H->Human,W->Wolf,S->Sheep,V->Vegetable)
最終輸出示例:HS H HW H
算法實現
使用python舉例
#!/usr/bin/env python3
# H->Human,W->Wolf,S->Sheep,V->Vegetable
name = ["H", "W", "S", "V"]
search_finish = False; # 用於判定 遞歸截止
# 完成狀態的判斷
def is_done(status):
return status[0] and status[1] and status[2] and status[3]
# 生成下一個局面的所有情況
def generate_next_status(status):
next_status_list = []
for i in range(0, 4):
if status[0] != status[i]: # 和農夫不在一側?
continue
next_status = [status[0],status[1],status[2],status[3]]
# 農夫和其中一個過河,i 爲 0 時候,農夫自己過河。
next_status[0] = not next_status[0] # 農夫自身取反
next_status[i] = next_status[0] # 和農夫一起過河
# 如果是安全的狀態, 那麼將本次狀態加入狀態列表
if is_valid_status(next_status):
next_status_list.append(next_status)
return next_status_list
# 判斷是否合法的局面 安全局面
def is_valid_status(status):
if status[1] == status[2]:
if status[0] != status[1]:
# 狼和羊同側,沒有人在場 不安全
return False
if status[2] == status[3]:
if status[0] != status[2]:
# 羊和草同側,沒有人在場 不安全
return False
return True
# 搜索程序
def do_search(history_status):
global search_finish
if search_finish:
return
current_status = history_status[len(history_status) - 1] # 獲取當前狀態
next_status_list = generate_next_status(current_status) # 生成下一次狀態
for next_status in next_status_list:
# 去重處理
if next_status in history_status:
continue
history_status.append(next_status) # 加入下一個狀態
# 完成後輸出
if is_done(next_status):
search_finish = True
print(get_solution(history_status))
else:
do_search(history_status) # 未完成則繼續搜索
history_status.pop()
#根據前後狀態輸出過河指標 過去的狀態和現在的狀態對比
def output_cross(pre, now):
res = [] # 用於存放當前數據
for i in range(len(pre)):
if pre[i] != now[i]:
res.append(name[i])
return ''.join(res)
#打印過程 根據歷史棧 轉換成 過河標識
def get_solution(history_status):
result = ''
hs_len = len(history_status)
for i in range(hs_len):
# output_cross
# 從第二個開始 比較
if i > 0:
result += output_cross(history_status[i-1], history_status[i])
# 不是最後一個
if i != hs_len - 1:
result += ' '
return result
if __name__ == "__main__":
# 初始化第一次狀態
status = [False, False, False, False]
# 初始化歷史狀態
history_status = [status]
# 觸發搜索
do_search(history_status)
最終輸出:
S H HW HS HV H HS