蓝桥杯——算法训练
问题描述:
住在有顶天的天人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
若有疑问欢迎下面留言