牛客网编程题目:数列计算

本文介绍了一种解决特定数列计算问题的方法,通过分析数列规律并结合二进制与目标进制间的转换技巧,高效求解数列中的指定项。文中详细解释了算法思路,并附带完整Python代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数列计算

数列计算

题目描述

已知一个正整数n,(3 <= n <= 15),将所有n的乘方幂以及所有n的乘方幂(有限个且互不相等)之和组成一个递增序列。例如,当n为4时,该序列为:
1, 4, 5, 16, 17, 20, 21……
(40, 41, 40+41, 42, 40+42, 41+42, 40+41+42……)
请求出该序列的第K项(10进制)。

输入描述:
输入只有1行,为2个正整数,两数之间用一个空格隔开:
n K
(n, K的含义与上述描述一致, 且3<=n<=15, 10<=K<=1000)。

示例1
输入 3 100 输出 981

老规矩,先给代码,再说思路。

import math
a, n = list(map(int,input().split()))
k = int(math.log(n,2))
res = 0
for i in range(k,-1,-1):
    count = n // (2**i)
    if count == 1:
        res += a**i
    n %= 2**i
print(res)

首先应该从二进制的角度思考这道题目。如果你足够细心,你会发现我的代码其实就是实现了如下功能:
计算 n 的二进制中 1 出现的位置,记录下所有的位置,然后将进制改为我们题目给定的进制,也就是代码中的 a 。计算进制为 a 时,实现上述记录的位置的值,即为答案。

举个例子,比如14这个数,其二进制是 1110,如果题目给定的进制是4,那么最终给定的答案就是 41+42+43。 如果不相信的话,自己可以用规律写出前16个,自己比对即可。

哈,原来就是进制替换这么简单,那么代码不难写出,这就是算法的魅力。可是如何看透本质呢?首先,我们是人不是神,要先观察规律,我列了一个表格

12345678
010+120+21+20+1+23
910111213141516
0+31+30+1+32+30+2+31+2+30+1+2+3

第一行和第三行是索引,不过是从1开始计数的,第二行和第四行分别是对应的 幂次。如果你足够细心,你应该发现了一些规律:

  1. 新的幂次 k 出现的次数是 2k。比如幂次 2 ,在幂次 3 出现之前,出现了4次,再如幂次 3 ,出现了8次。
    这个规律有用在这个地方,当我们要计算第100个数时,我们可以将最高幂次求解出来,这只是个等比数列求和公式的运用。幂次的求解就是代码中的 k = int(math.log(n,2))。需要解释吗?自己列公式就明白了,这里的公式我不会打,最多只能截图,太麻烦放弃了。
  2. 幂次的出现是嵌套的。比如新的幂次 2 出现时,除了新幂次,其余的幂次其实就是重复新幂次之前的幂次出现的顺序。同理,幂次 3 也是如此。
    这个规律有什么用呢?这恰恰就是进制位数的记录啊,这会难道还没发现幂次的记录其实就是依次递增数的二进制中1所在的位置吗?比如1,2,3,…这样一个递增的自然数列,每个数的二进制中1所在的位置的记录不就是上表中记录的吗 ?
  3. 进制替换为题目中要求的进制。输出答案即可!

这道题目,我下次看到,可能也会陷入做不出来的尴尬状态。算法题目,尤其是数学规律,需要长时间的实践和积累才能熟能生巧。没有天生的智者,只有偷懒的傻瓜。一天一篇博客,且行且珍惜!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值