蓝桥杯算法训练——搬走要石

蓝桥杯——算法训练

问题描述:
  住在有顶天的天人Tensi对自己的住处很不满。终于有一天她决定把门前碍眼的要石通通丢掉(怒扔要石)。控制要石自然是很容易的事,不过也会消耗灵力。假设搬走一块质量为1的要石会消耗1点灵力,而且由于要石都是连着放置的缘故所以每次除了搬走一颗,也可以搬走连续的任意数量的要石,自然质量是算在一起的。现在Tensi准备最多使用M次灵力,但是她太懒……所以每次只会使用同量的灵力, 也因为她太烂,所以也不愿意多花一点灵力……现在很懒的Tensi需要你帮她计算最少一次需要消耗多少灵力,能够在M次内把所有要石都丢到人间去……

输入格式:
  第一行两个数N,M,用一个空格分隔。1<=n<=1000,1<=m<=400
  表示一共有N颗要石需要搬走已经Tensi最多发动M次灵力。
  接下来包括N 个正整数 0<=ai<=40000 顺序表示每一颗要石的质量。

输出格式:
  输出一个数T
  表示Tensi 每次至少消耗T灵力。0<=T<=1000000
  如果无解输出-1.

样例输入:
5 3
1 2 1 1 1

样例输出:
3

数据规模和约定:
对于100%的数据,1<=n<=1000,1<=m<=400,0<=ai<=40000。
保证0<=T<=1000000。

解题思路:
由题意可知,该问题就是一共由N颗石头,要在M次之内搬完,石头可以搬一颗,也可以搬走连续的任意数量,并且每次用的力气必须少于一个数,问这个数是多少?
温馨提示:题意中同量是指每次用的灵力和石头质量一样,而不是说每次都使用同样的灵力,我第一次做这题的时候就在这里饶了很久
该题用的是二分法解决的
代码如下:

def fun(x):
    count = 1 #每次使用灵力的次数
    sum = 0  #这是每次使用灵力的和
    i = 0
    while i < len(stone) :
        sum += stone[i]
        if i == len(stone) - 1 and sum <= x:  #当总灵力小于一个数时,使用二分法缩小范围
            return True
        elif sum > x:  #当灵力和大于一个数时,抛出,进行使用第二次灵力,该索引还是不变
            sum = 0
            count += 1
            i -= 1
        elif sum == x:   #当灵力和相等时,则抛出
            sum = 0
            count += 1
        if count > M:  #最多使用M次灵力次数
            return False
        i += 1


N, M = map(int, input().split())
stone = list(map(int, input().split()))
L = 0
for i in stone:  #这里使用l//M是缩小范围,提高计算机速度
    L += i
L //= M
R = 1000000
min = 0
while L < R:
    mid = (L + R) // 2
    if fun(mid):
        R = mid - 1
        min = mid
    else:
        L = mid + 1
if min == 0:  #无解输出
    print(-1)
elif fun(min - 1):
    print(min - 1)
else:
    print(min)

输出结果如下:

D:\dist\python\python.exe D:/蓝桥杯训练题/搬走要石.py
5 3
16 15 14 13 11
29

若有疑问欢迎下面留言

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值