【kickstart round E 2020】toys Python题解 只过了test 1

谨以此篇献给和我一样看的懂题解但下手写代码有点困难的同学~
参考 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))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值