备战蓝桥杯Day15 - 队列

本文介绍了编程中的分糖果问题解决方案,涉及字典序排序和不同情况下的糖果分配策略,同时详细讲解了队列数据结构(包括环形队列和双向队列)及其基本操作。作者分享了学习心得,强调了在适当时候集中精力学习的重要性。
摘要由CSDN通过智能技术生成

一、每日一题 - 分糖果

从今天开始,就开始尝试蓝桥杯的真题了。主要是我觉得力扣上的题太难了,我做不出来,不如把更多的时间花在研究真题上。

大佬题解:

n,x = map(int,input().split())
S = input()
S = sorted(S)

# 第二种情况,只有前 m 个同学拿的到同价值的低价糖果,后 n - m 个同学拿的就是高价值的糖果;
if S[x-1] != S[0]:
    print(S[x-1])
else:
    # 第一种情况,同一批同学都能先拿到等价值的糖果,尽可能让后面的字符短
    if S[x] == S[-1]:
        print(S[x-1],end='')
        for i in range(x,n,x):
            print(S[i],end='')
    # 第三种情况,同一批同学拿到的等价值糖果不足(样例的情况)
    else:
        for i in S[x-1:]: # 假如俩同学,字符串为aabccd,则
            print(i,end='')

 详细解释:

这段代码的主要目的是处理一个与糖果分配有关的问题。首先,它接收两个整数输入 n 和 x,以及一个字符串 S。这个字符串 S 可能代表了一系列糖果的类型或价值。

  1. n 和 x 是通过 input().split() 获取的,它们分别被转换为整数并赋值给 n 和 x
  2. S 是另一个通过 input() 获取的字符串,代表糖果的类型或价值序列。
  3. 接下来,代码对字符串 S 进行排序,使其成为一个按字母顺序(或某种其他顺序,取决于 S 中元素的类型)排列的序列。

然后,代码进入了一个条件判断部分,根据 S 的不同特性来决定如何输出糖果的分配结果。

  • 第二种情况:如果第 x 个糖果(从1开始计数)与第一个糖果不同,那么第 x 个糖果就是第一个同学能拿到的最高价值的糖果。因此,代码输出第 x 个糖果的类型或价值。
  • 第一种情况:如果第 x 个糖果与第一个糖果相同,并且第 x+1 个糖果与最后一个糖果也相同,那么所有同学都可以先拿到等价值的糖果。代码输出前 x-1 个糖果的类型或价值,然后输出一个换行符,表示这一批同学已经完成了糖果的分配。
  • 第三种情况:如果第 x 个糖果与第一个糖果相同,但第 x+1 个糖果与最后一个糖果不同,那么同一批同学拿到的等价值糖果不足。在这种情况下,代码会输出从第 x 个糖果开始到字符串末尾的所有糖果的类型或价值。

需要注意的是,这段代码的输出是通过 print(S[i], end='') 完成的,这意味着输出不会在每个糖果类型或价值之后自动换行。只有在第一种情况下,才会在输出完前 x-1 个糖果后插入一个换行符。这可能意味着输出的结果需要在其他地方(如另一个程序或脚本中)进行进一步处理或解释。

 一开始感觉题目挺难懂的,主要是这个字典序,就跟英文字典排序一样,a如果是第一个字母,那么不管他后面跟多少字母,都会比开头是b的字符串的字典序小,所以题目中给的例子分出的结果是一个a,一个abccd,abccd是字典序最小的但是字符串最长的。弄明白这个这个题目应该就能理解一大半了,但是我还是不知道怎么去实现代码,所以先学习一下大佬的吧。

二、队列

基本概念

队列(Queue)是一种特殊的线性数据结构,它遵循特定的操作原则:先进先出(FIFO, First-In-First-Out)。这意味着第一个被添加到队列中的元素将是第一个被移除的元素。队列在多种应用场景中非常有用,比如任务调度、缓冲区管理、打印任务等。

队列的基本操作包括:

  1. 入队(Enqueue):在队列的末尾添加一个元素。
  2. 出队(Dequeue):从队列的开头移除一个元素,并返回该元素。
  3. 查看队首(Peek/Front):查看队列的第一个元素,但不移除它。
  4. 判断队列是否为空(Is Empty):检查队列中是否没有元素。
  5. 获取队列大小(Size):返回队列中元素的数量。

 实现方式:

1.环形队列(Circular Queue)

是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则,但其在内存中的存储是环形的。这意味着当队列满时,下一个元素会覆盖队列开始位置的元素,而当队列为空时,下一个元素会插入到队列开始的位置。为了实现环形队列,我们通常使用一个固定大小的数组和两个指针:一个指向队头(front),另一个指向队尾(rear)。

 

压栈:当栈不满时,将队尾指针向后移,元素赋值给新的空间。

出栈:当栈不空时,将队首指针向前移动,返回原来指向空间的值。

判断队空:当队尾指针与队首指针指向同一个时,说明这个栈是空的。

判断队满:当队尾指针加1后对整个列表的长度取余为0时,说明队列是满的。

class Queue:
    def __init__(self, size=100):
        self.queue = [0 for i in range(size)]
        self.size = size
        self.rear = 0   # 队尾指针
        self.front = 0   # 队首指针

    def push(self, element):   # 压栈
        if not self.is_filled()
            self.rear = (self.rear + 1) % self.size
            self.queue[self.rear] = element
        else:
            raise IndexError("Queue is filled")

    def pop(self):    # 出栈
        if not self.is_empty():
            self.front = (self.front + 1) % self.size
            return self.queue[self.front]
        else:
            raise IndexError("Queue is empty.")

    def is_empty(self):    # 判断队空
        return self.rear == self.front

    def is_filled(self):
        return (self.rear + 1) % self.rear == self.front

2.双向队列

使用列表(list)作为底层数据结构。虽然列表可以实现队列的基本功能,但它不是最优选择,因为列表的pop(0)操作(即移除第一个元素)的时间复杂度是O(n)。在实际应用中,更推荐使用collections.deque,因为它支持在两端添加和移除元素,且时间复杂度都是O(1)。 

代码实现 

class Queue:  
    def __init__(self):  
        self.queue = []  
  
    def enqueue(self, item):  
        self.queue.append(item)  
  
    def dequeue(self):  
        if not self.is_empty():  
            return self.queue.pop(0)  
        return None  
  
    def peek(self):  
        if not self.is_empty():  
            return self.queue[0]  
        return None  
  
    def is_empty(self):  
        return len(self.queue) == 0  
  
    def size(self):  
        return len(self.queue)

三、学习总结 

有三天没有学习了,兼职给小孩讲题太累了我感觉,每天回家就想躺床上,啥也不想干,所以最近学习很松懈,也快开学了,咱们就是一整个不想开学~~~不想回学校~~~哈哈哈但是还是要面对现实,也快出四级成绩了,最近整的也是挺焦虑的,然后更不想学习了。我秉持的理念就是不想学的时候就不学,强迫自己反而可能更不想学,但该学的时候还是要专注的好好学习,也不能一直不想学哈哈哈。这几天先整点简单的学习一下,开学了全身心地投入进学习中,咱们就是直接上难度了。祝自己加油吧!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值