问题描述:
10个小孩围城一圈分糖果,老师分给第1个小孩10块,第2个小孩2块,第3个小孩8块,第4个小孩22块,第5个小孩16块,第6个小孩4块,第7个小孩10块,第8个小孩6块,第9个小孩14块,第10个小孩20块。然后所有的小孩同时将手中的糖分一半给右边的小孩;糖块数为奇数的人可向老师要一块。
问经过这样几次后大家手中的糖的块数一样多? 每人各有多少块糖?
分析:
首先,糖的传递a[i]=(a[i]+a[i-1])/2,要用到小索引元素,所以应该从大到小遍历,记得每次循环前先取出a[9],最后加到a[0]
判断是否是奇数
构造全相等的判断函数
#构造糖块全相等的判断函数
def isequal(c):
for v in range(len(c)-1):
if c[v]!=sum(c)/len(c):
return False
#主体函数
a=[10,2,8,22,16,4,10,6,14,20]
k=1
while k < 100:
last=a[9]
a[0]=(a[0]+last)/2
if a[0]%2!=0:
a[0]=a[0]+1
for i in range(9,0,-1):
a[i]=(a[i]+a[i-1])/2
#此处在循环内直接判断是否是奇数。如果再来一个循环的话for i in range(10),复杂度大大增加。
if a[i]%2!=0:
a[i]=a[i]+1
k+=1
if isequal(a):
continue
print k,a
运行后出现以上结果,为什么k的返回值是100?难道都遍历了?找了一晚上的错误,才发现,原来是判断函数出错了。这样的判断函数,只要列表里面有一个平均数,则会输出True,所以并不能判定所有元素相等。所以即便k会一直循环下去,如下
修改判断函数:
#构造糖块全相等的判断函数
def isequal(c):
s=0
for v in range(len(c)-1):
if c[v]!=sum(c)/len(c):
s+=1
if s==0:
return True
这样运行结果才正确,break才起作用
总结:
1 判断函数构造错误
2 判断是否是奇数的时候,我开始用的是重新遍历一遍for i in range(10),复杂度大大增加,优化为在循环内直接判断。
3 开始将a[0]的赋值错误地放到了for i 循环里面了,这样每次a[0]都被累加赋值了,应该是外面,每次大循环赋值一次
4 平均数array.mean()只有在numpy数组才能用
修改,找错误,查询,反反复复做了两个小时╮(╯▽╰)╭ 但还是做出来了,还想到了算法优化减少时间复杂度,进步!