题解 | #反复横跳#
反复横跳
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)