问题描述:
有12个蛋,其中一个是坏蛋,但并不知道坏蛋比好蛋重还是轻,工具是天平,通过3次使用天平获取到坏蛋。
问题分析:
如果可以确定坏蛋比好蛋重还是轻,那么可以使用二分查找, 如,坏蛋轻与好蛋,第一次天平两端分别放6个,重的一方6个蛋为好蛋;将轻的一方再使用二分查找,可以得到轻的一方只有3个了;最后在随机选择两个蛋,放于天平,如果轻的为坏蛋,如果一样,那么还没有被称重的蛋为坏蛋。
求解思路
但是这里并不知道具体情况;因此采用等分成3份尝试,将蛋分为3分,分别编号1,2,3, 每份4个;分别编号,其中第一份: 0, 1, 2, 3; 第二份: 4, 5, 6, 7; 第三份: 8,9,10,11
1)
1.1) 首先称重1,2,先考虑两边相等的情况,那么坏蛋在第3份,
注意: 因为这里并不知道好蛋和坏蛋那个重,因此天平两边分别直接放两个蛋并没有意义,
1.2) 这里直接分别比较其中两个,如比较8,9,若一样重,那么比较8, 10,若相等,那么11就是坏蛋,若不等则10为坏蛋;若8,9不等且8,10等,那么9为坏蛋;若8,9不等,8,10也不等,那么8为坏蛋。
2)现在考虑第一份和第二分不等:
2.1) 将 第一份的0,1 与 第二份的4放在一起作为first_one, 将第一份的2,3 与 第二份的5作为first_two;
2.2) 比较 first_one 与 first_two, 若相等,那么坏蛋在 6,7 之间,将其与好蛋相比较,得坏蛋。
2.3) 若first_one < first_two 且 第一次比较时,one < two, 可得, 0,1,2,3 < 4, 5, 6, 7 且 0, 1, 4 < 2, 3, 5;那么当坏蛋重与好蛋时,5为坏蛋,反之坏蛋在0,1中,且坏蛋轻与好蛋,比较0,1若一样,5为坏蛋,反之,0,1中,轻的为坏蛋。
3) 同理可得其他情况。
代码实现
# -*- coding: utf-8 -*-
# __author__ : john
# email: john_rain_01@163.com
class solution(object):
def __init__(self):
import random
self.num_abnormal = random.randint(0, 11)
self.egg_number = {}
self.weight_abnormal = random.randint(0, 1)
def get_egg_number(self):
"""
param: None
return: dictionary there are twelve egg's
"""
if self.weight_abnormal:
for i in range(12):
self.egg_number[i] = 0
self.egg_number[num_abnormal] = 1
else:
for i in range(12):
egg_number[i] = 1
egg_number[num_abnormal] = 0
return egg_number
def third_weight(self, egg):
""" there are twelve eggs but one of these is bad, but we don't know that it is heaver or lighter,
and we have only three times to get the bad egg
param: a dictionary have the number of egg's
return: bad egg's number
"""
# spilt twelve eggs
one, two, three = 0, 0, 0
for i in range(4):
one += egg[i]
for i in range(4, 8):
two += egg[i]
for i in range(8, 12):
three += egg[i]
# for the first weight
# if 0,1,2,3 = 4,5,6,7 the bad egg is in the part three
if one == two:
if egg[8] == egg[9]:
if egg[8] == egg[10]:
return 11, egg[11]
else:
return 10, egg[10]
else:
if egg[8] == egg[10]:
return 9, egg[9]
else:
return 8, egg[8]
# if 0,1,2,3 < 4, 5, 6, 7
elif one < two:
first_one = egg[0] + egg[1] + egg[4]
first_two = egg[2] + egg[3] + egg[5]
if first_one == first_two:
if egg[0] == egg[6]:
return 7, egg[7]
else:
return 6, egg[6]
elif first_one < first_two:
if egg[0] == egg[1]:
return 5, egg[5]
elif egg[0] < egg[1]:
return 0, egg[0]
else:
return 1, egg[1]
else:
if egg[0] < egg[4]:
return 4, egg[4]
elif egg[2] < egg[3]:
return 2, egg[2]
else:
return 3, egg[3]
else:
# 0,1,2,3 > 4, 5, 6, 7
first_one = egg[0] + egg[1] + egg[4]
first_two = egg[2] + egg[3] + egg[5]
if first_one == first_two:
if egg[0] == egg[6]:
return 7, egg[7]
else:
return 6, egg[6]
# 0, 1, 4 < 2, 3, 5
elif first_one < first_two:
if egg[2] == egg[3]:
return 4, egg[4]
if egg[2] < egg[3]:
return 3, egg[3]
else:
return 2, egg[2]
# 0, 1, 4 > 2, 3, 5
else:
if egg[0] == egg[1]:
return 5, egg[5]
elif egg[0] < egg[1]:
return 1, egg[1]
else:
return 0, egg[0]
def main(self):
egg = self.get_egg_number()
return self.third_weight(egg)
if __name__ == "__main__":
sl = solution()
print(sl.main())