谷歌面试题:两个玻璃球摔碎的楼层高度

给你两个一摸一样的球,这两个球如果从一定的高度掉到地上有可能就会摔碎,当然,如果在这个高度以下往下扔,怎么都不会碎,当然超过这个高度肯定就一定摔碎了。现在已知这个恰巧摔碎高度范围在一层楼到100层楼之间。如何用最少的试验次数,用这两个玻璃球测试出摔碎的楼高。

两个球,一个用来粗调,一个用来精调,具体做法是这样的。

首先拿第一个球到10层楼去试,如果没有摔碎,就去20层楼,每次增加10层楼。如果在某个十层楼摔碎了,比如60层,就知道摔碎的高度在51到60层之间,接下来从51层开始一层层地试验,这样就可以保证不出二十次,一定能试出恰巧摔碎的高度。

这是从统计学的角度来说,最完美的策略。从工程学的角度看,这是考察一个人有没有掌握粗调和精调的方法,就像显微镜上有两个旋钮,第一个粗调,让你大致看到图像,第二个是精调,能让你看清楚图像。

stairs = int(input("Please input the total stairs: "))
def steps(step,target):
	i = j = 0
	while target > 0:
		target -= step
		i += 1
	j = target + step
	return i + j
 
steps_dict = dict()
for j in range(2,int(stairs/2) + 1,1):
	sum = 0.0
	for i in range(1,stairs + 1,1):
		sum += steps(j,i)
	print("step: %d, mean steps: %f" % (j, sum/stairs))
	steps_dict[j] = sum/stairs
	
temp_key = ""
temp_steps = stairs
for key in steps_dict.keys():
	if temp_steps > steps_dict[key]:
		temp_steps = steps_dict[key]
		temp_key = key
print("The best step should be %d and the mean steps is %f." % (temp_key, temp_steps))

运行结果:
PS F:\for_project\python> python .\steps_google.py
Please input the total stairs: 100
The best step should be 10 and the mean steps is 11.000000.
PS F:\for_project\python> python .\steps_google.py
Please input the total stairs: 1000
The best step should be 32 and the mean steps is 32.532000.
PS F:\for_project\python> python .\steps_google.py
Please input the total stairs: 200
The best step should be 14 and the mean steps is 15.050000.

 

假设我们每次选择从第x层楼往下扔球,如果球碎了,我们就知道楼高一定在1到x-1层之间,否则楼高一定在x+1到100层之间。因此,我们可以将这个问题转化为在1到100之间找到一个数字x,使得最坏情况下需要尽可能少的尝试次数。 首先,我们可以选择在第14层楼往下扔球,如果球没碎,我们再选择在第27层楼往下扔球,如果球还没碎,我们再选择在第39层楼往下扔球……一直到在第96层楼往下扔球。这样一来,如果球一直没碎,我们最多只需要尝试14次;如果球在某一层楼碎了,我们最多只需要尝试13次。 但是,这种方法并不是最优解。我们可以使用二分法来优化。具体做法如下: 1. 我们首先选择在50层楼往下扔球,如果球碎了,我们就知道楼高一定在1到49层之间,如果球没碎,我们就知道楼高一定在51到100层之间。 2. 然后,我们选择在25层楼或75层楼往下扔球,具体选择哪一层楼取决于第一次的结果。如果第一次球没碎,我们就在51到75层之间继续尝试;如果第一次球碎了,我们就在1到24层之间继续尝试。 3. 然后,我们选择在13层楼或38层楼或63层楼或88层楼往下扔球,具体选择哪一层楼取决于前两次的结果。如果前两次球都没碎,我们就在76到100层之间继续尝试;如果前两次球都碎了,我们就在1到12层之间继续尝试;如果第一次球没碎,第二次球碎了,我们就在51到62层之间继续尝试;如果第一次球碎了,第二次球没碎,我们就在1到24层之间继续尝试。 4. 以此类推,每次都选择中间层数的一半作为尝试的楼层,直到我们找到了恰好摔碎楼层。 使用二分法,最坏情况下我们只需要尝试7次就能找到恰好摔碎楼层。因此,使用二分法的方法是最优解。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值