问题描述:
烙饼问题可以简化为对一段由n个无重复的整数组成的无序数组a[n]进行排序。排序要求每次只能对a[0]~a[i]部分的数组进行翻转(0 < i < n),最终完成排序。
输入:数组大小n;n个整数。
输出:最小递归查找次数m;每次翻转位置j0j1…jm-1

问题思考:
烙饼排序这部分,主要考量的是对递归函数的使用。
而搜索上界与搜索下界则可以一定程度上提高代码的运行效率,减少搜索次数。
递归流程如下:
①首先进行0~i的翻转
②记录第step步翻转位置i
③然后进行下一层翻转
④调用递归返回之后,再进行一次0~i的翻转,保持数组进入本次循环时的顺序
①i++,进行0~i+1的翻转

for (int i = 1; i < m_nCakeCnt; i++)
{Revert(0, i);m_ReverseCakeArraySwap[step] = i;Search(step + 1);Revert(0, i);
}

稍微修改代码之后可以发现,最小翻转的解并不是唯一的。
测试输入:10,{ 5, 9, 4, 1, 2, 0, 8, 7, 6, 3 }
输出有效最优解:
14849278
15183931
15218393
15839312
19385312
19465853
19484278
19615285
|Search Times| : 159193
Total Swap times = 8

完整代码如下:

#include <stdio.h>
#include "stdafx.h"
#include "afx.h"class CPrefixsorting
{public:CPrefixsorting(){m_nCakeCnt = 0;m_nMaxSwap = 0;}void Run(int* pCakeArray, int nCakeCnt){Init(pCakeArray, nCakeCnt);m_nSearch = 0;Search(0);}//输出烙饼具体翻转的次数void Output(){for (int i = 0; i < m_nCakeCnt; i++){printf("%d", m_ReverseCakeArray[i]);}printf("\n");for (int i = 0; i < m_nMaxSwap; i++){printf("%d", m_SwapArray[i]);printf("\n");Revert(0, m_SwapArray[i]);for (int i = 0; i < m_nCakeCnt; i++){printf("%d", m_ReverseCakeArray[i]);}printf("\n");}printf("\n |Search Times| : %d\n", m_nSearch);printf("Total Swap times = %d\n", m_nMaxSwap);}
private://初始化数组信息void Init(int* pCakeArray, int nCakeCnt){ASSERT(pCakeArray != NULL);ASSERT(nCakeCnt > 0);m_nCakeCnt = nCakeCnt;//初始化烙饼数组m_CkaeArray = new int[m_nCakeCnt];ASSERT(m_CkaeArray != NULL);for (int i = 0; i < m_nCakeCnt; i++){m_CkaeArray[i] = pCakeArray[i];}//设置最多交换次数信息m_nMaxSwap = upBound(m_nCakeCnt);//初始化交换结果数组m_SwapArray = new int[m_nMaxSwap];ASSERT(m_SwapArray != NULL);//初始化中间交换结果信息m_ReverseCakeArray = new int[m_nCakeCnt];for (int i = 0; i < m_nCakeCnt; i++){m_ReverseCakeArray[i] = m_CkaeArray[i];}m_ReverseCakeArraySwap = new int[m_nMaxSwap];}//寻找翻转上界int upBound(int nCakeCnt){return nCakeCnt * 2;}//寻找翻转下界int LowerBound(int* pCakeArray, int nCakeCnt){int t, ret = 0;//根据当前数组的排序信息情况来判断至少需要交换多少次for (int i = 1; i < nCakeCnt; i++){//判断位置相邻的两个烙饼,是否为尺寸排序上相邻的t = pCakeArray[i] - pCakeArray[i - 1];if ((t == 1) || (t == -1)){}else{ret++;}}return ret;}//排序主函数void Search(int step){int i, nEstimate;m_nSearch++;//估算这次搜算所需要的最小交换次数nEstimate = LowerBound(m_ReverseCakeArray, m_nCakeCnt);if (step + nEstimate > m_nMaxSwap){return;}//如果已经排好序,即翻转完成,输出结果if (IsSorted(m_ReverseCakeArray, m_nCakeCnt)){if (step <= m_nMaxSwap){m_nMaxSwap = step;for (i = 0; i < m_nMaxSwap; i++){m_SwapArray[i] = m_ReverseCakeArraySwap[i];printf("%d", m_SwapArray[i]);}printf("\n");}return;}//递归进行翻转for (int i = 1; i < m_nCakeCnt; i++){Revert(0, i);m_ReverseCakeArraySwap[step] = i;Search(step + 1);Revert(0, i);}}bool IsSorted(int* pCakeArray, int nCakeCnt){for (int i = 1; i < nCakeCnt; i++){if (pCakeArray[i - 1] > pCakeArray[i]){return false;}}return true;}//翻转烙饼信息void Revert(int nBegin, int nEnd){ASSERT(nEnd > nBegin);int i, j, t;for (i = nBegin, j = nEnd; i < j; i++, j--){t = m_ReverseCakeArray[i];m_ReverseCakeArray[i] = m_ReverseCakeArray[j];m_ReverseCakeArray[j] = t;}}
private:int* m_CkaeArray;               //烙饼信息数组int  m_nCakeCnt;                //烙饼个数int  m_nMaxSwap;              //最多交换次数,根据前面的推断,这里最多为m_NCakeCnt*2int* m_SwapArray;               //交换结果数组int* m_ReverseCakeArray;        //当前翻转烙饼信息数组int* m_ReverseCakeArraySwap;    //当前翻转烙饼交换结果数组int  m_nSearch;                   //当前搜索次数信息
};int main()
{CPrefixsorting x;int array[10] = { 5, 9, 4, 1, 2, 0, 8, 7, 6, 3 };x.Run(array, 10);x.Output();getchar();return 0;
}

编程之美-1.3-烙饼排序问题相关推荐

  1. 编程之美 一摞烙饼的排序问题

    一摞烙饼问题其实是一个很有意思的问题,它的描述是让一摞随机顺序的烙饼通过单手翻转的方式进行排序,以达到这摞烙饼由小到大顺序放置在盘子上的目 的,其特点是每次翻转都会导致第一个烙饼到所要反转的那个烙饼之 ...

  2. 编程之美 一摞烙饼问题

    问题: 星期五的晚上,一帮同事在希格玛大厦附近的"硬盘酒吧"多喝了几杯.程序员多喝了几杯之后谈什么呢?自然是算法问题.有个同事说:"我以前在餐馆打工,顾客经常点非常多的烙 ...

  3. 编程之美 - 读书笔记 - 烙饼问题与搜索树

    前 面已经写了一些关于烙饼问题的简单分析,但因为那天太累有些意犹未尽,今天再充实一些内容那这个问题研究透.我想,通过这篇文章,我们就可以把这一类问题 搞懂.再遇到优化问题,如果我们想不到别的办法,就可 ...

  4. 编程之美之一摞烙饼的排序1

    拿到这个问题, 第一反应是利用分治的算法思想, 每次把当前的最大的一块烙饼放到指定位置 ,这样的思想非常简单,实现也非常容易.但是这只是提供了,问题的一个可行解,看完书中的内容之后发现,题目中要求的是 ...

  5. 编程之美-一摞烙饼的排序方法整理

    [问题描述] [方法]

  6. 思维的体操——勇者斗恶龙,编程之美-烙饼排序问题,买书问题(上)

    刚开学一周,时间还不忙,这周就看了这么点东西,赶紧写下来啊. 先说烙饼排序问题,我是看了书中的解法思路之后,突然联想到其实和汉罗塔问题非常像,都可以采用递归的方式来解决问题.而我的思路则很是直接 #i ...

  7. 《编程之美——微软技术面试心得》一摞烙饼的排序初体验

    <编程之美>读书笔记:1.3 一摞烙饼的排序 问题: 星期五的晚上,一帮同事在希格玛大厦附近的"硬盘酒吧"多喝了几杯.程序员多喝了几杯之后谈什么呢?自然是算法问题.有个 ...

  8. 【编程之美】一摞烙饼的排序

    一,问题:                     星期五的晚上,一帮同事在希格玛大厦附近的"硬盘酒吧"多喝了几杯.程序员多喝了几杯之后谈什么呢?自然是算法问题.有个同事说:&qu ...

  9. 编程之美-翻烙饼问题

    翻烙饼问题 前言 翻烙饼问题是非常经典的问题,星期五的晚上,一帮同事在希格玛大厦附近的"硬盘酒吧"多喝了几杯.程序员多喝了几杯之后谈什么呢?自然是算法问题.有个同事说: " ...

最新文章

  1. Windows内核实验004 API调用
  2. jquery.easyui常用示例
  3. AntiSpy:一款功能强大的反病毒反Rootkit免费工具套件
  4. python 存redis失败无提示_python如何关闭redis
  5. Docker系列教程06-实战:修改Nginx首页
  6. 多人在线答题游戏 小程序 (规划设计方案)
  7. UltraEdit,无法卸载,无法安装
  8. 守望先锋app(2)
  9. SylixOS -- 双网卡冗余备份使用说明
  10. c语言中自动生成迷宫地图,C语言新案例-迷宫制作
  11. Oracle ORA12514 监听程序当前无法识别连接描述符中请求的服务问题解决
  12. 什么是DNS污染?DNS污染怎么办怎么解决?
  13. photoshop之CameraRaw
  14. Java项目:图书管理系统(java+JSP+layui+bootstrap+Servlet+Mysql)
  15. C++基础学习笔记(五)——核心编程PART3
  16. 视觉SLAM十四讲-第九讲例程运行出错
  17. emby,jellyfin,kodi系列
  18. 机房服务器安装操作系统
  19. 炎炎夏日,深夜详谈nginx的配置中location和rewrite的语法规则(从入门到高手的第六步)
  20. uniapp 电商app 下载页面功能实现

热门文章

  1. 网约车风云再起:“小窗口”和“大窗口”齐开
  2. 牛客网 - [牛客假日团队赛5]金币馅饼(dp)
  3. 微信公众号 开发详解02【自动回复、发布文章、自定义菜单、3种链接跳转】
  4. 树莓派超声波测距原理及例子
  5. python re正则提取ip地址_python 正则表达式匹配IP地址
  6. HashMap集合常见方法
  7. SPI通信拓扑如何选择?
  8. python爬取物流信息_快递信息查询爬虫 python实现
  9. 谨慎使用 @MockBean注解
  10. CPC电商广告在复杂环境下需要考虑的要素