一摞烙饼的排序

    有大小不一的一摞饼在你的一只手上,现在你需要将饼由大到小翻转,即最大尺寸的饼在底部,最小尺寸的饼在最上面,而且你只能用一只手进行翻转。千言万语不如一张图。

    上图是三张饼的翻转,你是否能写出一个程序,对于n块大小不一的烙饼,输出最优化的翻饼过程?
解题思路:
1、 最笨的办法,一次翻转一个未排序中最大的饼需要两次翻转,那么n个饼就需要2*(n-1)次。当然这是最多的次数。
2、 万一翻转之前部分饼的顺序已经是排好的了,如此一想,这种情况下那翻转次数肯定会更少,但是这种情况还是比较难找。
3、 要找出最好的办法,最笨的办法,穷举吧!当然穷举的过程为了缩短次数,当以已经翻转的次数大于2*(n-1)那么那次穷举就可以停止了。跟进一步对当前序列进行翻转次数预估,预估次数加上已翻转次数大于2*(n-1),那么那次穷举就可以停止了。
    穷举的思路:上图。从左到有是:顶端-底端。

源码:

#include <iostream>using namespace std;class CPrefixSorting
{
private:int* m_CakeArray; // 烙饼信息数组int m_nCakeCnt;   // 烙饼个数int m_nMaxSwap;   // 最多交换次数,根据前面的推断,这里最多为 m_nCakeCnt*2int* m_SwapArray; // 交换结果数组int* m_ReverseCakeArray; // 当前翻转烙饼信息数组int* m_ReverseCakeArraySwap; // 当前翻转烙饼交换结果数组int m_nSearch; // 当前搜索次数信息
public:CPrefixSorting(){m_nCakeCnt = 0;m_nMaxSwap = 0;}~CPrefixSorting(){delete m_CakeArray;delete m_SwapArray;delete m_ReverseCakeArray;delete m_ReverseCakeArraySwap;}// 初始化烙饼信息:个数void init(int *pCakeArray, int nCakeCnt){// 初始化烙饼数组m_nCakeCnt = nCakeCnt;m_CakeArray = new int[nCakeCnt];for (int i = 0; i < m_nCakeCnt; ++i){m_CakeArray[i] = pCakeArray[i];}// 设置最多交换次数信息m_nMaxSwap = UpperBound(m_nCakeCnt);// 初始化交换结果数组m_SwapArray = new int[m_nMaxSwap];// 初始化中间交换结果信息m_ReverseCakeArray = new int[m_nCakeCnt];for (int i = 0; i < m_nCakeCnt; ++i){m_ReverseCakeArray[i] = m_CakeArray[i];}m_ReverseCakeArraySwap = new int[m_nMaxSwap];}void run(int*pCakeArray, int nCakeCnt){init(pCakeArray, nCakeCnt);m_nSearch = 0;search(0);}// 输出烙饼具体翻转次数void output(){for (int i = 0; i < m_nMaxSwap; ++i){cout << m_SwapArray[i]<<" ";}cout << endl << "|Search Times| :" << m_nSearch <<endl;cout << "Total Swap times = " << m_nMaxSwap << endl;}// 寻找当前翻转的上界int UpperBound(int nCakeCnt){return nCakeCnt * 2;}// 寻找当前翻转的下界int lowerBound(int* pCakeArray, int nCakeCnt){int t, ret = 0;// 根据当前数组的排序信息情况来判断最少需要交换多少次
// 要求饼大小间隔为1,故有待改进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);
// 预估次数加已翻转次数大于m_nMaxSwap就退出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_CakeArray[m_ReverseCakeArraySwap[i]];}}return;}// 递归进行翻转for (i = 1; i < m_nCakeCnt; ++i){// 翻转顶部饼到第i个饼reverse(0, i);// 记录翻转第i个饼序号m_ReverseCakeArraySwap[step] = i;// 进行下一轮翻转穷举search(step + 1);//若第step+1步的翻转失败,回复到第step步的翻转结果reverse(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 reverse(int nBegin, int nEnd){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;}}
};int main()
{int CakeArray[] = {4,2,3,1,5,6,7,9,8}; //顶端-底端int size = sizeof(CakeArray) / sizeof(CakeArray[0]);CPrefixSorting a;a.run(CakeArray,size);a.output();getchar();return 0;
}

编程之美 1.3 一摞烙饼的排序相关推荐

  1. 编程之美学习笔记--一摞烙饼的排序

    问题:假设有n块大小不一的烙饼,翻烙饼时只能从最上面的烙饼开始,一次抓住最上面的几块饼,把它们上下颠倒个儿,那么最少要翻多少次,才能够达到最后的大小有序? 思路 先上一张图,可以很好的说明思路: 假设 ...

  2. 1.3 一摞烙饼的排序

    1.3 一摞烙饼的排序 参考<编程之美–1.3 一摞烙饼的排序> 问题描述: 一摞乱序摆放的烙饼,每次只能抓取最上面几块烙饼并翻转,多次翻转后能够实现烙饼的从小到大(从上往下)的有序摆放. ...

  3. 《编程之美》1.3一摞烙饼的排序

    <编程之美>1.3一摞烙饼的排序       本文内容主要整理自http://yangguosheng.here.blog.163.com/blog/static/111479292201 ...

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

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

  5. 《编程之美》读书笔记(三):烙饼问题与搜索树

    <编程之美>读书笔记三:烙饼问题与搜索树 薛笛 EMail:jxuedi#gmail.com 前面已经写了一些关于烙饼问题的简单分析,但因为那天太累有些意犹未尽,今天再充实一些内容那这个问 ...

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

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

  7. 编程之美学习笔记(三):一摞烙饼的排序

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

  8. (1.5.1.3)编程之美:一摞烙饼的排序

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

  9. 一摞烙饼的排序(搜索树)

    前两个星期就看编程之美的一摞烙饼排序问题,刚开始看其代码没看懂什么意思,后来看了人家的博客才知道是怎么回事了,自己写了一遍其代码做各种各样的测试,吓我一跳,一个剪枝操作竟然省了那么多的时间,想起上一道 ...

最新文章

  1. Depth Bias
  2. mysql创建和删除用户
  3. xmlWriter 以UTF-8格式写xml问题
  4. observable_Java Observable setChanged()方法与示例
  5. ibatis Dynamic总结(ibatis使用安全的拼接语句,动态查询)
  6. python50行小游戏_使用Python写一个小游戏
  7. 塔设备设计手册_强烈推荐必备资料—化工设备设计手册 (上、下卷全)
  8. 弓箭传说微信小程序抖音小程序开发
  9. 计算机程序图标在哪,我的文档不见了 我的文档路径在哪 找回图标方法_电脑软硬件应用网_做中国最专业的计算机应用解决技术网站...
  10. How to change Intel WiFi Link 5100 AGN MAC addr(更改Intel WiFi Link 5100 AGN MAC地址)
  11. excel服务器条形码不显示,excel怎么制作条形码教程 excel条形码显示不出怎么办...
  12. 使用AnyGantt创建Word Tree
  13. NLP入门概览(9) ——句法分析c:局部句法分析、依存关系分析
  14. 华为 2017 实习生招聘笔试题
  15. mysql 计算近30天总金额_计算月嫂每天工资,应该用总工资除以30天还是26天?-免费法律咨询...
  16. 基于主成分分析法的安全评价模型
  17. Centos 7安装、配置SVN
  18. 阿里云k8s一键部署有状态StatefulSet nacos2.0.3
  19. 亚马逊工程师:我曾拼命逃离996,Fuck You money!
  20. Golang教程:(十三)Map

热门文章

  1. 中国式家长——旅行者困境
  2. 一生应该必看的20个故事
  3. squirrelSql小松鼠数据库连接工具的安装以及连接informix(系列3,squirrelSql作为客户端连接)
  4. 深入理解java虚拟机第3版 周志明
  5. PS合成图片#ps抠图#ps视频教程入门基础学习课程小白
  6. 安装office2016专业增强版
  7. 2022(秋)工程伦理答案 第九章
  8. OSS: cURL error: Empty reply from server (52)
  9. 用java编写租车系统代码_java实现租车系统
  10. docker健康检查