演算法題 李嘉誠保險櫃密碼問題

2021-09-25 01:43:31 字數 1354 閱讀 4871

據說,李嘉誠的保險櫃密碼是乙個 8 位的數字。他經常更換密碼,但換密碼的規則很簡單,每次都把密碼的數字 * 3,如果有位數溢位,就把最前面的那個數字挪到整個數字末尾加起來 —— 比如 98765432 就會變成 98765432 * 3 = 296296296, 但是這有 9 位, 把最前面的 2 加到末尾, 變成 96296298, 就是新密碼。現在我們偷到了李嘉誠的保險櫃,而且我們知道他最初的密碼是 00000001, 已經迭代了 n 次,求乙個演算法,可以在 o(log n) 的時間內算出密碼。

迭代分析第n次的密碼計算公式:

x0= 0000 0001

x1= (3 * x0) % 108 + (3 * x0) / 108,顯然,x1

< 108

x2= (3 * x1) % 108 + (3 * x1) / 108

=  % 108 + / 108

=  % 108 + (顯然其值<9) % 108 

+  / 108 +  / 108

(顯然其值趨於0)

= (32 * x0) % 10(由分配率得)

+ (32 * x0) / 108 

+ [(32 * x0) % 108 ] / 108

(趨於0忽略) + 0

= (32 * x0) % 10+ (32 * x0) / 108

x3 = (33

* x0) % 10+ (33 * x0) / 108

以此類推可得:

xn = (3n

* x0) % 10+ (3n * x0) / 108

又因:x0 = 1,所以:xn = 3n % 10+ 3n / 108

關於計算3n:

1、簡單處理的話可以n個3聯乘,時間複雜度o(n),當n較大時比較耗時,此題暫時不考慮大數問題;

2、當n為偶數時,3n=[3(

n/2)]2,當n為奇數時,3n=3*2,時間複雜度o(log n),此為最優解法。

python實現如下:

def g(x):

return x % 100000000 + x // 100000000

def f(x):

if x == 1:

return 3

elif x % 2 == 0:

return g(f(x / 2) * f(x / 2))

elif x % 2 == 1:

return g(f(1) * f(x - 1))

if __name__ == '__main__':

print(f(50))

演算法 常見演算法題

演算法題 假如有100個不相同的數,比如從1到100,怎樣使用10次取出其中的10個不同的數字,要求每個數取出的概率一樣 一開始沒有說10次,所以我說,使用乙個random函式,以時間為種子來取,當取出乙個時,做標記,下次再取到這個數時,重新取一次 然後他就說了如果只能夠取10次怎麼辦?一開始我想到...

基礎演算法題

1.一百萬富翁遇到一陌生人,陌生人找他談乙個換錢的計畫,計畫如下 我每天給你十萬,而你每天只需要給我一分錢,第二天我仍然給你十萬元,你給我二分錢,第三天我仍然給你十萬,你給我四分錢.你每天給我的錢是前天的兩倍,直到乙個月 30天 百萬富翁很高興,欣然接受拉這個契約.請編寫乙個程式計算這乙個月中陌生人...

演算法題筆記

1 請給出乙個o nlogn 的演算法,使之能夠找出乙個n個數的序列中最長的單調遞增子串行。這是演算法導論中的一道課後題。解法一 利用求最長公共子串行的思想,將n個數的序列a先排序形成乙個有序的序列b,然後利用動態規劃的思想求a與b的最長公共子串行,得到的最長公共子串行就是所求的解。但是我們知道最長...