手機的九宮格圖案解鎖總共能繪出多少種圖案?

taoqick發表於2018-09-03

需要滿足的要求有:
至少經過四個點;
不能重複經過同一個點;
路徑上的中間點不能跳過(如從1到3一定會經過2);
如果中間的點是之前已經用過的,那麼這個點就可以被跳過(如213,因為2已經被用過,1就可以越過2與3連線,132是不允許的)。

作者:linkwun
連結:https://www.zhihu.com/question/24905007/answer/29414497
來源:知乎
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
 

from itertools import chain, permutations

impossible = {'13': '2', 
              '46': '5', 
              '79': '8', 
              '17': '4', 
              '28': '5', 
              '39': '6', 
              '19': '5', 
              '37': '5',
              '31': '2',
              '64': '5',
              '97': '8',
              '71': '4',
              '82': '5',
              '93': '6',
              '91': '5',
              '73': '5'}

def counts():
    iterlst = chain(*(permutations('123456789', i) for i in range(4, 10)))
    count = 0
    for i in iterlst:
        stri = ''.join(i)
        for k, v in impossible.items():
            if k in stri and v not in stri[:stri.find(k)]:
                break
        else:
            count += 1
    return count

print(counts())#389112

我用python寫了段程式碼,先計算出所有大於四個數字的所有排列組合,然後從中剃除穿過中間那個數字的組合,剩下的既為符合要求的程式碼。
例如13組合是不可能存在的,因為它會穿過2,19組合也不可能存在,因為它會穿過5,總共有16個這樣的組合。
但是假如中間這個數字已經用過了,是可以穿過的,比如213,2已經用過了,1是可以穿過2與3連線的。
如此篩選以後,就得到正確答案389112了。

以下兩段codes可以看做是等價的,只是chain的效率更高:

    iterlst = chain(*(permutations('123456789', i) for i in range(4, 10)))
    count = 0
    for i in iterlst:

for permutation in ((permutations('123456789', i) for i in range(4, 10))):
    for item in permutation:
        print(item)

 

相關文章