青蛙换位的回溯问题并不是一个很复杂的问题,其中回溯就可以用迭代和递归的方法来实现,本人这里就只用递归回溯法了。本文章主要是参考了huey2672的一篇博客[青蛙换位],并对将其改为C++版本的。
主要的思路呢就是在每进行下一步跳跃的时候就下搜索所有的石块上可以移动的青蛙,并依次移动,每一步中都需要保存当前跳动的青蛙所在的位置到step[n](n表示当前的步数),这样方便之后的打印青蛙跳动的过程。并且需要保留当前的空位所在的位置,将用来把青蛙放回原处,来实现回溯,具体的实现过程在代码中都有详细的说明。
这里就不多啰嗦了,直接“上菜”。

#include <iostream>
#include <fstream>
#include <algorithm>using namespace std;#define GREEN 1     //表示公青蛙
#define RED 2       //表示母青蛙
#define EMPTY 0     //表示空位
#define NUM 7       //石头的数目
#define MAXSTEP 20      // 完成移位可能需要的步数void recursive_backtrack(int n);//递归回溯法
bool can_shift(int i);                  // 判断在第i个石头上青蛙是否能移位
void frog_shift(int i);                 // 在第i个石头上青蛙移位
int where_empty();                      // 计算空位的位置
bool is_success();                      // 判断是否已经完成所有移位
void print_result();                    // 打印结果
void print_stone();                     //打印石头的状态//stone[i]表示第i+1个石头上的状态是公青蛙、母青蛙还是空
static int stone[NUM] = { GREEN, GREEN, GREEN, EMPTY, RED, RED, RED};//记录下每一步中,移动的青蛙所在的石头下标,最终打印过程有用
static int step[MAXSTEP] = {-1};int main()
{for(size_t i = 0; i < MAXSTEP; i++)step[i] = -1;recursive_backtrack(0);system("pause");return 0;}/*
** 递归回溯法求解
** n表示递归的深度数,即执行的步骤
*/
void recursive_backtrack(int n)
{if(is_success()){print_result();return;}else{int empty_lastpost;//从第1块(对应下标0)石头上开始计算可以移动的frogfor(size_t i = 0; i < NUM; i++){//记录下这步中空位的初始位置,方便回溯empty_lastpost = where_empty();//如果第i+1块石头上的青蛙可以移动if(can_shift(i)){//移动第i+1块石头上的青蛙frog_shift(i);//记录下第n步跳动的青蛙所在石头的下标step[n] = i;//进入下一次的递归recursive_backtrack(n+1);//回溯,将青蛙移回原来的位置 frog_shift(empty_lastpost);}}}
}/*
** 判断在第i个石头上青蛙是否能移位
*/
bool can_shift(int i)
{int empty_post = where_empty();//记录下空位所在的位置switch(stone[i]){case GREEN:if(empty_post > i && empty_post <= i+2)return true;break;case RED:if(empty_post < i && empty_post >= i-2)return true;break;case EMPTY:default:return false;break;}return false;
}/*
** 在第i块石头上的青蛙进行移位
*/
void frog_shift(int i)
{swap(stone[where_empty()], stone[i]);
}/*
** 计算空位的位置
*/
int where_empty()
{int i;for (i = 0; i < NUM; i++)if (stone[i] == EMPTY) break;return i;
}/*
** 判断是否已经完成所有移位
*/
bool is_success()
{if (stone[0] == RED &&stone[1] == RED &&stone[2] == RED &&stone[3] == EMPTY &&stone[4] == GREEN &&stone[5] == GREEN &&stone[6] == GREEN)return true;return false;
}/*
** 打印结果
*/
void print_result()
{size_t i;for(i = 0;i < NUM; i++){if(i < 3)stone[i] = GREEN;else if(i > 3)stone[i] = RED;else if(i == 3)stone[i] = EMPTY;}print_stone();for (i = 0; i < MAXSTEP; i++) {if (step[i] == -1)break;swap(stone[where_empty()], stone[step[i]]);print_stone();}cout << endl;
}/*
** 打印石头的状态
*/
void print_stone()
{for(size_t i = 0; i < NUM; i++){if(stone[i] == GREEN)cout << "GREEN ";else if(stone))))))
)![![tp://bl](https://img-blog.csdn.net/20161129110336509)](https://img-blog.csdn.net/20161129110325166
i] == RED)cout << "RED ";else if(stone[i] == EMPTY)cout << "EMPTY ";}cout << endl;
}

输出结果如下:
(http://blog.csdn.net/huey2672/article/details/8897770)

青蛙换位问题之递归回溯法相关推荐

  1. 剑指offer:矩阵中的路径(递归回溯法DFS类似迷宫)

    1. 题目描述 /*请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.如果一条路径经 ...

  2. 递归回溯法求数独全部解

    项目介绍 QT5做的数独求解程序,可以判断数独解的个数(如果非唯一解). 运行截图 源码说明 使用MSVC + QT5平台,故* .cpp和* .h文件均采用UTF8 + BOM编码.如果切换到Min ...

  3. 非递归求解N皇后问题(回溯法)

    一般而言,回溯法可以说是一种穷举法,适合于求解各种深度优先搜索的问题. 回溯法是一种应用广泛的算法.其关键点是解空间树和n元组可行解的定义. 非递归回溯法程序的结构基本上是相同的,该程序的结构可以用求 ...

  4. 青蛙换位java_青蛙换位

    问题描述: 在7块石头上,有绿.红青蛙各3只, 绿青蛙在左边面向右,红青蛙在右边面向左,中间是个空位.每次移动一只青蛙,青蛙只能往前跳一步,或隔着一只青蛙跳一步,将左边的绿青蛙移动到右边,将右边的红青 ...

  5. 回溯法|Backtracking

    回溯法 回溯是一种算法,用于捕获给定计算问题的部分或全部解决方案,特别是约束满足问题.该算法只能用于能够接受"部分候选解"概念的问题,并允许快速测试候选解是否可以是一个完整的解.回 ...

  6. c语言实现全排列并存储,C语言实现全排列和回溯法总结

    一.递归实现全排列 #include"cstdio" int A[]; void print_permutation(int n,int *A,int cur){ if(cur== ...

  7. 回溯法——设计一个算法在1、2、3... 9(顺序不能变)数字之间插入+ 或 - 或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性和全排列

    回溯法 题目描述: 设计一个算法在1.2.3- 9(顺序不能变)数字之间插入+ 或 - 或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性.例如1+2+34-5+67-8+9=100 分 ...

  8. 分油问题回朔法c语言算法,用回溯法求“韩信分油”问题所有解

    裴南平 摘要:回溯法是一种常用的计算机程序设计方法.使用回溯法解决"韩信分油问题"也称"泊松分酒问题",在算法中保存每一步执行的中间结果,程序扩展前,判斷程序是 ...

  9. 算法分析五:回溯法与分⽀限界法

    一.回溯法 1. 基本思想与解题步骤 基本思想: 把问题的解空间转化成了图或者树的结构表⽰,然后使⽤深度优先搜索策略进⾏遍历,遍历的过程中记录和寻找所有可⾏解或者最优解. 解题步骤: 针对所给问题,定 ...

最新文章

  1. 爆料:当我们跟VC聊天时,他们都会问些什么?
  2. 机器学习从理论到工程的第二步-开发环境与工具篇
  3. 《Asp.Net 2.0 揭秘》读书笔记(九)
  4. Oracle基础 TO_CHAR函数参考(转)
  5. c语言单片机常用函数,C51单片机C语言函数编辑 -单片机-电子工程世界网
  6. DirectX9 3D 快速上手 1
  7. 篮球30秒可控计时器
  8. C语言中的数据类型及输出格式
  9. GTP-U 5GS用户面GTP协议解析
  10. 深度学习模型压缩方法概述
  11. 产品快速迭代需要注意点
  12. bat脚本学习——拖拽文件到bat下载
  13. 东北大学计算机学院教授,东北大学之计算机系
  14. IE不兼容HTML5、CSS3解决方法
  15. docker初学记录--运行应用程序
  16. 华硕路由域名访问_“618” WiFi6 路由器选购推荐清单_路由器
  17. 关于整合ssh的问题,新人求关照
  18. 好的中层管理者要兼顾公司和员工的利益
  19. Keep It for Mac(专业笔记工具)
  20. python中entry的使用方法_Python3.7 - tkinter Gui 05 Entry的使用

热门文章

  1. 虚拟摄像头之 十二 v4l2loopback虚拟机摄像头移植实战(完结篇)
  2. 西门子PLC Wincc大型程序scl+梯形图变频器G120 伺服 S120 远程终端ET200SP
  3. 说说著名的计算机科学家和他们的代表成就,说一说你知道的科学家和他们的成就...
  4. 智慧农场、智慧农业管理系统、农作物、农技指导、四防棚、农耕、种植、农事执行、地块、圈地、加热温室、圈养、生产、采收记录、采收计划、采收入库、销售、农资溯源记录、农场日志、axure原型、产品原型、rp
  5. go语言逐行读取和写入文件
  6. GitHub开源社区 最火的Android开源项目
  7. 桌面便签程序的实现详解和源码 (上)
  8. 一篇学会:mysql锁表查询和解锁操作
  9. PAT 1010 一元多项式求导
  10. 微信小程序客服系统手机版五大功能介绍