农夫、羊、狼、菜的过河问题

问题描述

  • 角色:农夫,羊,狼,菜
  • 条件1:船很小,只能装下农夫和其他一个角色
  • 条件2:无人看管,羊吃菜,狼吃羊
  • 问:如何让其他三种角色被农夫平安带着过河?

相关分析

  • 我们可以先用人脑尝试一下相关渡河策略

    • 1 ) 先渡狼,人回来再渡菜,人回来再渡羊
    • 2 ) 先渡菜,人回来再渡狼,人回来再渡羊
    • 以上两种很好想到,而且我们可以知道羊这种角色是不能先渡河过去的,羊需要最后再渡
    • 如果先渡了羊了,之后再渡任何其他角色,都要将羊带回来
    • 可以参考小游戏:http://gameschool.cc/game/178 自己尝试一下
  • 我们需要让计算机来计算出来可行的方案
    • 使用策略:枚举
    • 相关算法设计
      • 解决问题的算法有很多种,这里仅提供一种
      • 将此问题抽象为状态和行为的变化
      • 以渡河与否作为判断状态条件
      • 未渡河(在河岸的一侧)状态:0,行为:0
      • 渡河(到河岸的另一侧)状态:1,行为:1
      • 算法是切换各个角色的渡河与未渡河状态进行枚举,得到最终结果(一种可行的方案)

算法实现

#include <cstdio>
#include <cassert>
#include <cstring>// 状态值只有两种 0, 1
struct  State {int h; // 人 humanint w; // 狼 wolfint s; // 羊 sheepint v; // 菜 vegetable
};// 渡河函数
State pass(State s, char role) {// 切换人的状态s.h =  1 - s.h;if(role == '-') {// do nothing} else if(role == 'W') {// 渡狼 切换狼的状态s.w = 1 - s.w;} else if(role == 'S') {// 渡羊 切换羊的状态s.s = 1 - s.s;} else if(role == 'V') {// 渡菜 切换菜的状态s.v = 1 - s.v;} else {// 直接崩溃,方便调试assert(0);}return s;
};// 标记已尝试的策略
bool passed[2][2][2][2];// 检测状态是否合法
bool invalid_state_check(State s) {// 人和羊不在一边,且羊和狼在一起if(s.h != s.s && s.s == s.w) return true;// 人和羊不在一边,且羊和菜在一起if(s.h != s.s && s.s == s.v) return true;return false;
};// 检测是否为最终状态
bool final_state_check(State s) {// 最终状态为:人,狼,羊,菜都已渡河if(s.h == 1 && s.w == 1 && s.s == 1 && s.v == 1) return true;return false;
};// 结果集 开辟一个较大的空间
char result[1000];// 打印结果
void print_result(int step) {for(int i = 0; i < step; i++) {if(i != 0) {printf(" ");}printf("H");if(result[i] != '-') {printf("%c", result[i]);}}puts("");
};// 开始尝试 false 停止
bool go(State s, int step) {// 调试输出// printf("%d %d %d %d\n", s.h, s.w, s.s, s.v);// 判断是否合法if(invalid_state_check(s)) {return false;};// 判断是否最终if(final_state_check(s)) {// 打印结果print_result(step);return true;};// 判断是否已经尝试if(passed[s.h][s.w][s.s][s.v]) {return false;};// 标记已尝试策略passed[s.h][s.w][s.s][s.v] = true;// 处理下一个状态 next stateState ns;ns = pass(s, '-');result[step] = '-';if(go(ns, step+1)) return true;// 渡狼if(s.h == s.w) {result[step] = 'W';ns = pass(s, 'W');if(go(ns, step+1)) return true;};// 渡羊if(s.h == s.s) {result[step] = 'S';ns = pass(s, 'S');if(go(ns, step+1)) return true;};// 渡菜if(s.h == s.v) {result[step] = 'V';ns = pass(s, 'V');if(go(ns, step+1)) return true;};return false;
};// main函数
int main() {memset(passed, 0, sizeof(passed));State init_state = {0, 0, 0, 0};go(init_state, 0);return 0;
};

最终结果

  • 输出:HS H HW HS HV H HS
  • 解释:先渡羊,人单独回来,再渡狼,人带着羊回来,再渡菜,人回来,最后渡羊

数据结构与算法笔记:计算思维之经典农夫过河问题C++实现相关推荐

  1. 数据结构与算法笔记 - 绪论

    数据结构与算法笔记 - 绪论 1. 什么是计算 2. 评判DSA优劣的参照(直尺) 3. 度量DSA性能的尺度(刻度) 4. DSA的性能度量的方法 5. DSA性能的设计及其优化 x1. 理论模型与 ...

  2. 数据结构与算法笔记(十五)—— 散列(哈希表)

    一.前沿 1.1.直接寻址表 当关键字的全域U比较小时,直接寻址是一种简单而有效的技术.假设某应用要用到一个动态集合,其中每个元素都有一个取自全域U={0,1,-,m-1)的关键字,此处m是一个不很大 ...

  3. 数据结构稀疏矩阵的加法十字链表_学习数据结构和算法的框架思维

    ----------- 通知:如果本站对你学习算法有帮助,请收藏网址,并推荐给你的朋友.由于 labuladong 的算法套路太火,很多人直接拿我的 GitHub 文章去开付费专栏,价格还不便宜.我这 ...

  4. 数据结构与算法笔记(青岛大学王卓老师视频)

    写在前面的话: 因为在学习数据结构之前,学习过一年的算法,所以有一些基础,一些我觉得 没必要的代码或知识就没写上,记得多是一些知识点,写的可能对于别人来说 很难接受,望谅解.我学习算法是在Acwing ...

  5. 数据结构与算法的学习——思维的学习与高屋建瓴

    数据结构与算法的学习--思维的学习与高屋建瓴 一.算法思维的练习 二.练习过程 1.是什么(WHat) 2.怎么用(How) 三.进阶思考 1.栈的思考 2.树的问题 3.关于递归 (1)排列组合问题 ...

  6. labuladong的算法小抄_学习数据结构和算法的框架思维

    ----------- 通知:如果本站对你学习算法有帮助,请收藏网址,并推荐给你的朋友.由于 labuladong 的算法套路太火,很多人直接拿我的 GitHub 文章去开付费专栏,价格还不便宜.我这 ...

  7. JS数据结构与算法 笔记

    JS数据结构与算法笔记 前言:不定时更新说明 1. 栈(Stack) 1.1 基于数组实现栈 1.2 基于对象实现栈 1.3 基于链表实现栈 1.4 栈的简单应用 1.4.1 字符串中的括号匹配问题 ...

  8. 数据结构与算法笔记(王卓网课+教材+大话数据结构)

    数据结构与算法笔记(王卓网课+教材+大话数据结构) ##最新整理!!! 顺序存储结构的线性表P10-P21 顺序线性表的代码实现 链式线性表笔记 串笔记 绪论.算法(P1-P9)1.4数据起源结构 数 ...

  9. 数据结构与算法笔记(十六)—— 二叉搜索树

    一.二叉搜索树定义 二叉搜索树(Binary Search Tree),又名二叉排序树(Binary Sort Tree). 二叉搜索树是具有有以下性质的二叉树: 若左子树不为空,则左子树上所有节点的 ...

最新文章

  1. 机器学习XGBoost——后面的明天更
  2. java jedis使用_Java中使用Jedis操作Redis
  3. 关于c++ pair自己遇到的一个问题?为何不一样?为何第一个程序不能返回pair内数组的值呢?(已经解决)
  4. tensorflow中GPU的设置
  5. leetcode - 898. 子数组按位或操作(使用了集合)
  6. 女子800米跑进4分30秒才合格,茅台回应应聘者需体测...
  7. python selenium安装
  8. 华为鸿蒙科技创新,华为、美的合作:搭载鸿蒙系统的家电来了 三大亮点
  9. js控制分页打印、打印分页示例
  10. 蓝牙学习笔记(四)——AC692x程序烧录
  11. C# 的基本数据类型
  12. Altium Designer AD 2019最新封装库下载,原理图库PCB库
  13. 产品读书《大数据时代:生活、工作与思维的大变革》
  14. js常用的加密/解密方法
  15. 南通大学计算机专业校区,南通大学计算机科学与技术专业
  16. 百度ai 性别_是的,ai可能是种族主义者和性别歧视者,所以我们该怎么办
  17. shell 字符串列表长度
  18. 关于RundownProtect到底是什么东西
  19. PLC控制技术与组态技术实训装置
  20. JavaScript的输出与变量

热门文章

  1. 介绍python库的书籍_【介】 介怎么读|组词|读音|拼音|多音字|意思 - 辞海之家
  2. 示波器常用的13个概念
  3. 常见的引脚功能介绍(基于ADSP-SC589芯片)
  4. 使用Kong和Konga管理微服务和API
  5. Charles浏览器抓包配置
  6. Vue-高德地图-立体多边形绘制
  7. Android实现关机代码
  8. 关于AQS中自旋的理解
  9. java volatile
  10. 2022年终的断舍离