题解 | #反复横跳#

反复横跳

https://ac.nowcoder.com/acm/contest/12949/E

整体思路,先构建出反复横跳的数组

[0, 1, -1, 3, -5, 11, -21, 43, -85, 171, -341, 683, -1365, 2731, -5461, 10923, -21845, 43691, -87381]

然后对把两个人的位置相减,可能是正也可能是负,假设这个数字为8200,则8200位于[2731,10923]之间,那应该取哪个呢?两种思路,要么多走一些,先走10923步,再走-2731步,要么少走一些,先走2731步,再走5469步,至于取哪种,由于时间紧迫,通过在数字比较小(3到11之间一个一个试)的时候观察大概推理得到如果一个数位于[2731,8192]之间,取2731,如果位于[8192,10923]之间,取10923,至于8192这个数字怎么来。8192=(10923-2731)/3*2+2731,即把[2731,10923]分成三份,前两份就取2731,后一份取10923。之后就不停迭代就好了,负数同理。

顺便建立一个字典用来处理[-5,5]的情况以提高效率。

x = 0
op = 1
step = 1
shuzu = [0]

for i in range(18):
    x += op * step
    op = -op
    step = step * 2
    shuzu.append(x)
x = list(map(int, input().split()))

zidian = {-5: 4,
          -4: 6,
          -3: 8,
          -2: 5,
          -1: 2,
          0: 0,
          1: 1,
          2: 3,
          3: 3,
          4: 5,
          5: 6}


cha = x[1] - x[0]
bushu = 0
flag = True

while flag:
    for i in range(1, len(shuzu)):
        if cha > 5:
            if shuzu[i - 1] <= cha < (shuzu[i + 1] - shuzu[i - 1]) / 3 * 2 + shuzu[i - 1]:
                bushu += i
                cha = cha - shuzu[i - 1]
                break
            if (shuzu[i + 1] - shuzu[i - 1]) / 3 * 2 + shuzu[i - 1] <= cha <= shuzu[i + 1]:
                bushu += i + 2
                cha = cha - shuzu[i + 1]
                break
        elif cha < -5:
            if shuzu[i - 1] >= cha >= (shuzu[i + 1] - shuzu[i - 1]) / 3 * 2 + shuzu[i - 1]:
                bushu += i
                cha = cha - shuzu[i - 1]
                break
            if (shuzu[i + 1] - shuzu[i - 1]) / 3 * 2 + shuzu[i - 1] > cha >= shuzu[i + 1]:
                bushu += i + 2
                cha = cha - shuzu[i + 1]
                break
        else:
            bushu += zidian[cha]
            flag = False
            break
print(bushu)
全部评论

相关推荐

不愿透露姓名的神秘牛友
11-24 20:55
阿里国际 Java工程师 2.7k*16.0
程序员猪皮:没有超过3k的,不太好选。春招再看看
点赞 评论 收藏
分享
11-09 11:01
济南大学 Java
Java抽象带篮子:外卖项目真得美化一下,可以看看我的详细的外卖话术帖子
点赞 评论 收藏
分享
点赞 评论 收藏
分享
8 收藏 评论
分享
牛客网
牛客企业服务