1. 程式人生 > >饑餓的小易(枚舉+廣度優先遍歷(BFS))

饑餓的小易(枚舉+廣度優先遍歷(BFS))

其中 尋找 net inpu 最大 size ron sdn style

題目描述

小易總是感覺饑餓,所以作為章魚的小易經常出去尋找貝殼吃。最開始小易在一個初始位置x_0。對於小易所處的當前位置x,他只能通過神秘的力量移動到 4 * x + 3或者8 * x + 7。因為使用神秘力量要耗費太多體力,所以它只能使用神秘力量最多100,000次。貝殼總生長在能被1,000,000,007整除的位置(比如:位置0,位置1,000,000,007,位置2,000,000,014等)。小易需要你幫忙計算最少需要使用多少次神秘力量就能吃到貝殼。

輸入描述:

輸入一個初始位置x_0,範圍在1到1,000,000,006

輸出描述:

輸出小易最少需要使用神秘力量的次數,如果使用次數使用完還沒找到貝殼,則輸出-1

示例1

輸入

125000000

輸出

1

分析:

  這道題我們只能把每步都分為兩種情況,使用神秘力量1(4 * x + 3)和使用神秘力量2(8 * x + 7)。從出發點開始枚舉

,使用廣度優先遍歷算法(BFS)。由於貝殼出現在能被1,000,000,007整除的位置,所以我們只需要考慮%1000000007後的結果。我們要記錄初次到達某個位置時使用了幾次神秘力量。

第一種方法:

from collections import deque
mod = 1e9+7
n = int(raw_input().strip())
currentPos = n%mod
power = {}
power[currentPos] = 0
d = deque()
d.append(currentPos)
flag = False
while len(d):
    currentPos = d.popleft()
    
if power[currentPos] > 100000: break if currentPos == 0: flag = True break nextPos = (4*currentPos+3)%mod if nextPos not in power: power[nextPos] = power[currentPos]+1 d.append(nextPos) nextPos = (8*currentPos+7)%mod if nextPos not in power: power[nextPos]
= power[currentPos]+1 d.append(nextPos) if flag: print(power[currentPos]) else: print(-1)

第二種方法:

觀察變換形式,並做變形:

4x+3=4(x+1)-1

8x+7=8(x+1)-1

如果多層嵌套呢?

y=4x+3

8y+7=8((4(x+1)-1)+1)-1=8(4(x+1))-1=32(x+1)-1

如果你多枚舉一些,就會發現,能變換出的數的形式都是:

a(x+1)-1,其中a是2的>=2的冪次數(4、8、16、32、64、……)

我們可以利用這個特點

考慮直接枚舉那個a,從2^2一直到……等等,最大是2的多少次?

答:直接考慮最大情況,每次變換都選擇8x+7那種,也就是,每次a乘上8,也就是說,最壞是(2^3)^100000=2^300000次

所以,枚舉a,從2^2次,一直到2^300000次

然後,對每個a檢查一下,乘起來結果%1e9+7是不是0,如果是0,說明100000次之內有解

——問:那最小要執行幾次變換?

答:我們直接貪心,盡量讓a乘8(乘2次8和乘3次4一樣大,當然是乘8越多,變換次數越少)

——問:如果我發現a==2^5或a==2^4的時候滿足要求,但是5和4才不能表示成3的倍數,怎麽辦?

答:別忘了你手上還有4x+3的變換(就是a乘4的變換)

對5這種情況,除以3余2,那剛好,用一次乘4的變換就行了

對4這種情況,除以3余1,我們考慮,消去一個乘8的變換,用2個乘4的變換代替並補足。

n = int(raw_input().strip())
mod = int(1e9+7)
ans = -1
time = 4
for i in range(1,300001):
    x = (n*time+time-1)%mod
    if x == 0:
        ans = (i+1)/3
        if (i+1)%3:
            ans += 1
        break
    time = (time*2)%mod
print(ans)

第二種方法要比第一種方法高效一點

參考博客:

http://blog.csdn.net/fcxxzux/article/details/52138964#t0

饑餓的小易(枚舉+廣度優先遍歷(BFS))