zoukankan      html  css  js  c++  java
  • 【牛客网刷题】饥饿的小易

    题目描述

    小易总是感觉饥饿,所以作为章鱼的小易经常出去寻找贝壳吃。最开始小易在一个初始位置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++编写的,思路也几乎类似。

    【遗留问题】
    能否直接判断某个初始值达不到目标,通过数字的位特征来判断,这样的话就省去了十万次循环?
  • 相关阅读:
    记一道有趣的数学题
    BJOI2018 二进制
    BJOI2016 IP地址
    BJOI2016 回转寿司
    BJOI2017 开车
    BJOI2019 光线
    java 下载
    springboot 运行相关命令
    sql mapper 里面 Integer 类型判断
    springboot 访问jar同级别下的文件访问问题
  • 原文地址:https://www.cnblogs.com/zhangwei22/p/9950513.html
Copyright © 2011-2022 走看看