谨以此篇献给和我一样看的懂题解但下手写代码有点困难的同学~
参考 HallStattMia 大神的代码,感觉大神的思路跟官方题解是一样的。(但改写成python后只能过小数据,大数据TLE了again),怒学C++
解题思路
(按官方题解里的变量定义)
Ri 为记忆存续时间,Ei为玩的时间
SUM为所有玩具Ei之和
那当Ri+Ei>SUM时,表明该玩具在第二轮会造成中断;
步骤:
1 先把所有玩具按Ri+Ei之和排序,用heap降序存储;
2 堆不为空时,判断Ri+Ei是否超出SUM,如果是则去掉该玩具,同时更新SUM为SUM-Ei;遇到不超过SUM的玩具,则break;
3 若此时堆中还有玩具,则表明剩下的玩具可被一直玩啊玩;否则,说明不存在无线玩下去的情况,需要具体计算在第二轮的时候玩多久;
4 把heap清空,然后开始按玩具的序号从小到大添加(Ri+Ei, Ei, Ri),此处Ri可省略。添加后判断当前heap堆顶元素是否打破了规则,如果是则移除它,同时更新SUM和s,SUM是第一轮的时间和,s是第二轮的时间和;如果否,则break
5 不断更新第一轮加第二轮时间和;
(python这个heap只是小根堆,那就取反按小根堆来算。csdn上有文章指出按大根堆来用maxpush结果不对)
代码
import heapq as hq
T=int(input())
for tt in range(T):
N=int(input())
toys=[]
heap=[]
cur_time=0
SUM=0
for nn in range(N):
ee,rem=[int(s) for s in input().split(' ')]
toys.append([ee+rem,ee,rem])
hq.heappush(heap, [-(ee+rem),ee,rem])
cur_time+=ee
SUM+=ee
del_ans=0
while heap:
top=hq.nsmallest(1,heap)
if -top[0][0]>SUM:
SUM-=top[0][1]
hq.heappop(heap)
del_ans+=1
else:
break
if del_ans<N:
ans=del_ans
will='INDEFINITELY'
else:
SUM=cur_time
s=0
dell=0
del_ans2=0
while heap:
heap.pop()
for nn in range(N):
ty=toys[nn]
ee=ty[1]
rem=ty[2]
hq.heappush(heap,[-(ee+rem),ee,rem])
s+=ee
while heap:
top=hq.nsmallest(1,heap)
if SUM+top[0][0]<0:
SUM-=top[0][1]
s-=top[0][1]
hq.heappop(heap)
dell+=1
else:
break
if SUM+s>cur_time:
cur_time=SUM+s
del_ans2=dell
ans=del_ans2
will=cur_time
print('Case #{}: {} {}'.format(tt+1,ans,will))