1. 程式人生 > >Python練習(21)-分糖果-中

Python練習(21)-分糖果-中

問題描述:

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陣列才能用

修改,找錯誤,查詢,反反覆覆做了兩個小時╮(╯▽╰)╭ 但還是做出來了,還想到了演算法優化減少時間複雜度,進步!