【编程练习】小强去春游

题目来源:牛客,阿里巴巴编程题(2星),第3题

题目描述

在这里插入图片描述
在这里插入图片描述
从样例就可以看出,在选择由谁往回划的时候有两种选择方法。
对样例1([2,10,12,11])来说,每次都由最轻的人往回划,这种方法是最省时的;
对样例2([2,3,7,8])来说,如果每次都由最轻的人往回划,这种方法的耗时为22,而样例2给的答案是19。

这时需要转换思路,先搞清楚19是怎么来的:
令time=0;
第一次“往”:2和3一起,time+=3;
第一次“返”:2独自回来,time+=2;
第二次“往”:7和8一起,time+=8;
第二次“返”:3独自回来,time+=3;
第三次“往”:2和3一起,time+=3;
结束,总耗时time=3+2+8+3+3=19。

假设我们从河流左岸出发是“往”,从河流右岸回来是“返”。
至此,我们需要判断什么时候由左岸最轻者“返”,什么时候需要由右岸最轻者“返”。

题解

法一:超时的方法
我在判断由谁负责“返”时,采用了模拟的方法,会不断产生insert和pop的操作,所以超时了,代码如下:
【每一段错误的代码也有被记住的权利-----来自菜狗的卑微】
称“由左岸最轻者“返””的方法为法1,称“由右岸最轻者“返””的方法为法2。
以一次往返为单位,比较两种方法的耗时time和收益gain(即对面增加的重量),由此判断方法选择。
很显然,这样很慢。

def main():
    T = int(input())
    for i in range(T):
        n = int(input())
        left = [int(ni) for ni in input().split()]
        left.sort()
        if n==1:
            print(left[0])
            continue
        elif n==2:
            print(left[1])
            continue
        ans,right = left[0]+left[1],[left.pop(1)]
        while len(left)>2:
            minleft = left[0]
            maxleft = left[-1]
            time1 = maxleft+minleft
            gain1 = maxleft
            midleft = left[-2]
            minright = right[0]
            time2 = maxleft+minright
            gain2 = maxleft+midleft-minright
            if gain1-gain2>time1-time2:
                ans+=time1
                left.pop()
                right.append(maxleft)
            else:
                ans+=time2
                left.pop()
                left.pop()
                right.append(midleft)
                right.append(maxleft)
                left.insert(1,minright)
        ans += left[-1]
        print(ans)
    return

if __name__=='__main__':
    main()

法二:正解
以“两次来回”为单位,比较两种方法的耗时。
当左岸人数小于等于3时,则无须考虑方法选择。

def main():
    T = int(input())
    for i in range(T):
        left,ans = int(input()),0
        nums = [int(ni) for ni in input().split()]
        nums.sort()
        while left>0:
            if left==1:
                ans+=nums[0]
                left=0
            elif left==2:
                ans+=nums[1]
                left=0
            elif left==3:
                ans+=sum(nums[:3])
                left=0
            else:
                t1 = nums[0]*2+nums[left-1]+nums[left-2]
                t2 = nums[0]+nums[1]*2+nums[left-1]
                ans+=min(t1,t2)
                left-=2
        print(ans)
    return

if __name__=='__main__':
    main()

总结:

解题思路上,太乱【每日一emo】

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值