1. 程式人生 > >【牛客網刷題】飢餓的小易

【牛客網刷題】飢餓的小易

題目描述

小易總是感覺飢餓,所以作為章魚的小易經常出去尋找貝殼吃。最開始小易在一個初始位置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

 

小易有兩種移動方式,f(x)=4*x+3 或者 g(x)=8*x+7,通過f g函式的相互作用,可以找出規律:假如小易初始位置x0,移動後位置為 2^n * x0 - (2^n-1)。

如:16*x+15, 32*x+31, ..., 1024*x+1023, ...

找到n的發展規律,和n的數值即可。

 

看了別人的解析:f(x)=4*x+3 ,g(x)=8*x+7 可以進一步分別分解為2次,3次的2*x+1,那麼可以將F(x)=2*x+1作為元操作。

計算需要多少次元操作完成任務,然後將元操作儘量合併為g(x),這樣可以減少整體步數。

 

用Python寫了程式碼如下:

import time
x0 = int(input())
start_time = time.time()
n_max = 300000
p_food = 1000000007
x = x0
i = 0
times = 1
while i <= n_max + 1:
    if x % p_food == 0:
        break

    x = (x << 1) + 1
    i += 1

if i % 3 == 1 or i == n_max + 2:
    print(-1)
else:
    print(int(i/3 + i % 3 / 2))

print(time.time()-start_time)

  由於Python的計算效率較低,這樣的程式碼提交執行不通過,因為超時了。

使用

289869954
作為初始值計算,PC機本地執行23秒。

看到別人提交通過的答案,全部都是C++編寫的,思路也幾乎類似。

【遺留問題】
能否直接判斷某個初始值達不到目標,通過數字的位特徵來判斷,這樣的話就省去了十萬次迴圈?