魔术师发牌问题 -- python实现
问题描述
魔术师手中有A、2、3……J、Q、K十三张黑桃扑克牌。在表演魔术前,魔术师已经将他们按照一定的顺序叠放好(有花色的一面朝下).魔术表演过程为:一开始,魔术师数1,然后把最上面的那张牌翻过来,是黑桃A;然后将其放到桌面上;第二次,魔术师数1、2;将第一张牌放到这些牌的最下面,将第二张牌翻转过来,正好是黑桃2;第三次,魔术师数1、2、3;将第1、2张牌依次放到这些牌的最下面,将第三张牌翻过来正好是黑桃3;……直到将所有的牌都翻出来为止.问原来牌的顺序是如何的.
正确结果: [1, 8, 2, 5, 10, 3, 12, 11, 9, 4, 7, 6, 13]
解决方案
1. 列表
def solution_list(): pokers = [0 for _ in range(13)] # 初始化 count = len(pokers) # 纸牌总数 index = -1 for num in range(1, 14): i = 0 # 计数 while i < num: index = (index + 1) % count # 索引向前一步(可循环) if pokers[index] == 0: # 当前元素为0时才计数, 不为0则跳过 i += 1 pokers[index] = num print('#' * 50) print(f'\n牌组: {pokers}\n') print('#' * 50)
2. 单循环链表
class Node: """节点""" def __init__(self, value): self.data = value self.next = None def __repr__(self): return f'Node: {self.data}' class CircularLinkedList: """单循环链表""" def __init__(self): self.rear = None # 尾节点 def is_empty(self): return self.rear is None def append(self, elem): """尾插法""" temp = Node(elem) if self.rear is None: temp.next = temp self.rear = temp else: temp.next = self.rear.next self.rear.next = temp self.rear = temp def print_all(self): """ 按顺序打印全部节点 """ if self.is_empty(): return p = self.rear.next # 取得头部节点 print('Head', end='') while True: print('-->', p.data, end='') if p is self.rear: # 到达尾部停止 break p = p.next print('-->Finish') def solution_circular_linked_list(): pokers = CircularLinkedList() for _ in range(13): pokers.append(0) temp = pokers.rear for num in range(1, 14): i = 0 while i < num: temp = temp.next if temp.data == 0: i += 1 temp.data = num print('#' * 50) print('\n牌组: ') pokers.print_all() print('\n' + '#' * 50)