蛋糕切分
描述
林克被造的纪念日快要到了。根据任天堂公司的惯例,每年到这个时间都会一些蛋糕分给林克的朋友。这些蛋糕有不同的口味,比如南瓜蛋糕、坚果蛋糕、西瓜蛋糕、胡萝卜蛋糕、水果蛋糕等等(有N种不同口味,大小不同的蛋糕)。
为了公平,每个朋友都会分到一块大小相同的蛋糕(不需要同样形状,但是要同一种口味,不允许混合口味,否则就会变成奇怪的菜肴)。
假设每个蛋糕都是一个高为1,半径不等的圆柱体,一共有F+1个人(F是林克的朋友个数,还要加上林克的设计者)。
所有人拿到的蛋糕是同样大小的,请问每个人拿到的蛋糕最大是多少?
输入
第一行包含两个正整数N和F,1 ≤ N, F ≤ 10 000,表示蛋糕的数量和朋友的数量。
第二行包含N个1到10000之间的整数,表示每个蛋糕的半径。
输出
输出每个人能得到的最大的蛋糕的体积,精确到小数点后三位。
样例
3 3
4 3 3
25.133
难度
中等
解法
首先对蛋糕的大小进行排序,对没人能得到的最大蛋糕体积进行二分查找,查找区间为left = 最小蛋糕体积/该分的人数,right = 最大蛋糕体积。
Hasenoughcake函数用于判断蛋糕是否够分,如果不够分,right = mid, 如果够分,left = mid +eps 。eps为一个很小的数。
需要注意最后的输出格式和pi的精度。
代码
import math
# 输入
x = input()
x = x.split(' ')
N = (int)(x[0])
F = (int)(x[1])+1 #多一个设计者
y = input().split(' ')
cake = []
eps = 1e-6
for i in range(N):
cake.append((int)(y[i])**2*math.pi)
cake.sort(reverse = True)
def hasenoughcake(size):
if(size<eps):
return True
count = 0
for i in range(len(cake)):
if(cake[i]<size):
continue
elif(cake[i]>=size):
pieces = (int)(cake[i]/size)
count += pieces
if(count>=F):
return True
else:
return False
def binarySearch():
left = cake[-1]/F
right = cake[0]
while(left<right):
mid = (left+right)/2
if(hasenoughcake(mid)):
left = mid + eps
else:
right = mid
return left
ans = binarySearch()
print("%.3lf"%ans)