【Python算法复现】烙饼排序问题

问题描述

引用自以下博客

星期五的晚上,一帮同事在希格玛大厦附近的“硬盘酒吧”多喝了几杯。程序员多喝了几杯之后谈什么呢?自然是算法问题。有个同事说:“我以前在餐 馆打工,顾客经常点非常多的烙饼。店里的饼大小不一,我习惯在到达顾客饭桌前,把一摞饼按照大小次序摆好——小的在上面,大的在下面。由于我 一只手托着盘子,只好用另一只手,一次抓最上面的几块饼,把它们上下颠倒个个儿,反复几次之后,这摞烙饼就排好序了。我后来想,这实际上是个 有趣的排序问题:假设有n块大小不一的饼,那最少要翻几次,才能达到最后大小有序的结果呢?你能否写出一个程序,对于n块大小不一的烙饼,输出 最优化的翻饼过程呢?

问题解法

首先,我们将最大和最上面的烙饼的位置倒换:

在这里插入图片描述
接下来,我们将中间夹着的部分在进行翻转得到如下的饼堆:
在这里插入图片描述
再接下来,我们将最上面和最下面的互换,并将中间的饼再翻转:
在这里插入图片描述
由于翻转过后,我们恒知道有一块饼最终将不参与排序,这也就意味着我们最多只需要重复n-1次的排序操作即可。

代码编写

class MyPanCake:
    def __init__(self,cakeCounts=5) -> None:
        self.cakeCounts = cakeCounts
        self.cakes = [] # 创建一个放饼的“盘子”
        self.makeCakes()
        self.result = [] # 创建一个排好序的盘子“副本”
    def makeCakes(self):
        # 创建一个元组列表,分别存储饼的编号和大小
        self.cakes = [(i+1,self.cakeCounts - i) for i in range(self.cakeCounts)]
        print(self.cakes)
    def sortCakes(self):
        for i in range(self.cakeCounts-1):
            # 取出最大的那一张饼
            largest = max(self.cakes,key=lambda x:x[1])
            largestIndex = self.cakes.index(largest)
            # 临时拿个盘子存着这张病
            temp = self.cakes[largestIndex]
            # 判断第一张饼是不是最大的饼
            if largestIndex == 0:
                # 如果是,则忽略
                pass
            else:
                # 如果不是,则将最大的那张饼放到最上面,并把最上面的饼放到最大的那张饼的位置
                self.cakes[largestIndex] = self.cakes[0]
                self.cakes[0] = temp
            # 将中间部分翻转
            self.cakes[1:-1].reverse()   
            # 将最大的那张饼放到最下面
            theLast = self.cakes[-1]
            self.cakes[-1] = self.cakes[0]
            self.cakes[0] = theLast
            # 再将中间部分翻转
            self.cakes[1:-1].reverse()
            # 将最后一块饼从前向后插入到结果中
            self.result.append(self.cakes[-1])
            print(f"Cakes left : {self.cakes}")
            # 将最后一块饼从饼堆中删除
            self.cakes.pop(-1)
        # 最后一块饼堆里的饼就是排序后的“最底下”的那块饼
        self.result.append(self.cakes[0])
        # 将结果翻转,使其从小到大排列
        self.result.reverse()
    def getResult(self):
        print(f"Cakes after sorting (ascending=True) : {self.result}")
if __name__ == "__main__":
    cake = MyPanCake()
    cake.sortCakes()
    cake.getResult()

运行结果

Cakes on plate are : [(1, 5), (2, 4), (3, 3), (4, 2), (5, 1)]
Cakes left : [(5, 1), (2, 4), (3, 3), (4, 2), (1, 5)]
Cakes left : [(4, 2), (5, 1), (3, 3), (2, 4)]
Cakes left : [(4, 2), (5, 1), (3, 3)]
Cakes left : [(5, 1), (4, 2)]
Cakes after sorting (ascending=True) : [(5, 1), (4, 2), (3, 3), (2, 4), (1, 5)]

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Day(AKA Elin)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值