题目链接
浅浅地记录我自己的洛谷刷题情况
这一题做的可真是花费了我九六二虎之力,因为python容易超时,不管我自己怎么苦思冥想,都总是不能AC,后面终于找到用Python做的方法了,也学到了许多
#样例1
输入:
4
1 0
2 1
1 0
2
3
3
输出:
2 4 1
N = int(input())
queue = [1]
def put(people, k, p):
# people:入队的人
# k:要在几号同学旁边入队
# p:在他的左边还是右边
idx = queue.index(k) # 找到k的下标
if p == 0: # 如果要在k同学的左边入队
queue.insert(idx, people)
else:
queue.insert(idx + 1, people)
def out(s):
for i in s:
queue.remove(i)
for people in range(2, N + 1):
k, p = map(int, input().split())
put(people, k, p)
M = int(input())
s = set()
for i in range(M):
s.add(int(input()))
out(s)
n = len(queue)
for i in range(n):
if i != n - 1:
print(queue[i], end=" ")
else:
print(queue[i])
然而我小看了普及难度的题目,他果断给我抛出了
后面我看了以下数据大小,100000这说大不大说小不小的数字,让进行插入和删除操作的时候,因为列表是在内存空间里面一段连续的区域,每次插入删除都要移动后面的数据,100000这么多次反复操作,时间损耗可想而知
2.于是我查了以下,发现这题应该用链表实现,因为链表的插入和删除不用移动后面的数据,这样他的时间复杂度应该是可以大大缩小的,然而,当我满是自信的交出下面的代码时
class Node:
def __init__(self, item):
self.item = item
self.next = None
self.pre = None
class LinkList:
def __init__(self, head=None):
self.head = head
def append(self):
node = Node(1)
self.head = node
def insert(self, number, k, p):
node = Node(number)
cur = self.head
while cur:
if cur.item == k: # 找到要插入的位置
if p == 0: # 如果要站在他的左边
if not cur.pre:
self.head = node
node.next = cur
cur.pre = node
return
else:
cur.pre.next = node
node.pre = cur.pre
node.next = cur
cur.pre = node
return
else:
node.next = cur.next
cur.next.pre = node
cur.next = node
node.pre = cur
return
cur = cur.next
def pop(self, lst):
count = 0 # 已经删除的元素的个数
while count < len(lst):
cur = self.head
while cur:
if cur.item in lst:
if not cur.pre:
self.head = cur.next
cur.next.pre = None
elif not cur.next:
cur.pre.next = None
else:
cur.pre.next = cur.next
cur.next.pre = cur.pre
count += 1
cur = cur.next
def print_llst(self):
cur = self.head
while cur:
if cur.next:
print(cur.item, end=" ")
else:
print(cur.item)
cur = cur.next
L = LinkList()
L.append()
N = int(input())
for number in range(2, N + 1):
k, p = map(int, input().split())
L.insert(number, k, p)
M = int(input())
del_s = set()
for i in range(M):
del_s.add(int(input()))
L.pop(del_s)
L.print_llst()
OJ给了我狠狠的一把掌,让我无限接近与崩溃边缘
这让我百思不得其解,到底是什么问题呢?于是我认真的反思我的这些代码,发现每次插入和删除的时候我都需要遍历整个链表,这使得我的代码执行效率大大降低,终于,让我发现了别人的优秀的代码,我发现他用列表巧妙的处理了这一问题,最终,得出了我的AC代码
class Node:
def __init__(self, date, prev, next):
self.date = date
self.prev = prev
self.next = next
self.flag = True
N = int(input())
a = [None] * (N + 1)
a[0] = Node(0, a[0], a[0])
a[1] = Node(1, a[0], a[0])
a[0].next = a[1]
a[0].prev = a[1]
for i in range(2, N + 1):
k, p = map(int, input().split())
if p == 0:
a[i] = Node(i, a[k].prev, a[k])
a[k].prev.next = a[i]
a[k].prev = a[i]
else:
a[i] = Node(i, a[k], a[k].next)
a[k].next.prev = a[i]
a[k].next = a[i]
M = int(input())
for i in range(M):
x = int(input())
a[x].flag = False
cur = a[0]
while cur.next != a[0]:
cur = cur.next
if cur.flag != False:
print(cur.date, end=" ")
# if cur.next == a[0]: # 可以不要
# print()