问题描述
农夫(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