【牛客网刷题】饥饿的小易
题目描述
小易总是感觉饥饿,所以作为章鱼的小易经常出去寻找贝壳吃。最开始小易在一个初始位置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
小易有两种移动方式,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++编写的,思路也几乎类似。
【遗留问题】
能否直接判断某个初始值达不到目标,通过数字的位特征来判断,这样的话就省去了十万次循环?