首页 > 试题广场 >

计数器

[编程题]计数器
  • 热度指数:3826 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

小爱有一个奇怪的计数器。在第一个时刻计数器显示数字3,在接下来的每一个时刻,屏幕上的数字都会减1,直到减到1为止。

接下来,计数器会重置为上一个计数周期初始值的两倍,然后再每一个时刻减1。具体过程如下图所示:

找出规律,并打印出t时刻计数器的值。

输入描述:
输入为时刻t,一个整形数字。0<t<1e12


输出描述:
计数器显示的值。
示例1

输入

4

输出

6
找规律可以得到答案的数学公式。
首先,以这个计数器一次循环作为一组,可以发现对于第i轮循环,这个计数器会跳过的数字的数量是。那么,跳完了第j组的所有数字后,这个计数器总共跳过的数字数量由等比数列求和公式可以得到是
现在,我们希望求得第t个数的数值,就需要确定第t步所在的组。我们前面已经跳过了k组,那么应有,可以解得。显然,k为一个整数,因此取。这里需要特别注意的是,当为整数的时候,这个解应该减1才能满足小于条件(因为向下取整不会取到比这个整数小)。不过,我们可以发现,当t满足这个情况的时候,计数器的值为1,因此可以直接输出1。
现在我们知道前面跳了k组了,那么计数器在第t时刻就在第组。第组的起始数值为。前面k组已经占用的时刻数,也就是跳过的数量为,因此要跳到第t时刻还要再跳次。跳完这么多次后计数器上显示的数值,也就是答案,为

AC代码:
import math


class MainActivity:

    def main(self):
        # Read the data
        t = int(input())
        # Calculate the result
        k = math.log2(t / 3 + 1)
        if math.floor(k) == k:
            print(1)
            return
        k = math.floor(k)
        result = 3 * 2 ** k - (t - 3 * (2 ** k - 1)) + 1
        print(result)


if __name__ == '__main__':
    M = MainActivity()
    M.main()
发表于 2024-09-02 16:23:38 回复(0)