360笔试18年编程题第三题

题目:

现在有q个询问,每次询问想问你在[l,r]区间内,k进制表示中,k-1的数量最多的数是哪个数。比如当k=2时,9的二进制就是1001,那么他就有2个1.

输入:

第一行一个q,表示有q组询问。

接下来q行,每行三个整数k,l,r,分别表示进制数,查询的数字,以及查询的范围。

满足1<=q<=100000,2<=k<=16,1<=l<=r<=10^16

输出:

对于每组询问,输出答案。如果有多个答案,请输出最小的。

思路:首先定义两个函数,一个是十进制转化为其他进制,一个是其他进制转化为十进制。然后我们将输入的区间l和r分别转化为对应的k进制,并用列表保存,分别为start和end。(注意:start列表和end列表存储的可能是一个两位数,当k>10时,并且start的长度可能小于end,因此需要进行一个对齐操作。)最后我们将start数组从低位到高位依次将数值更改为k-1并且和十进制的r进行比较,判断是否溢出也就是是否大于边界(注意:此时时间复杂度可能较高,导致没有全部通过。),如果溢出则直接返回该值,此时就是所求的结果,即范围内k进制中含k-1个数最多的数。

python代码如下:

def num2k(k,num)://十进制转化为k进制
    s=[]
    while num//k:
        s.append(num%k)
        num=num//k
    s.append(num)
    s=list(reversed(s))
    return s
def k2num(k,s)://k进制转化为十进制
    sum=0
    tmp=1
    for i in range(len(s)-1,-1,-1):
        sum+=s[i]*tmp
        tmp*=k
    return sum
def find_num():
    q=int(input())
    f=[]
    for _ in range(q):
        s=[int(x) for x in input().split()]
        start=num2k(s[0],s[1])
        end=num2k(s[0],s[2])
        final=[s[1]]
        for i in range(0,len(end)-len(start)):
            start.insert(0,0)
        for i in range(len(start)-1,-1,-1):
            start[i]=s[0]-1
            final.append(k2num(s[0], start))
            if final[-1]>s[2]:
                f.append(final[-2])
                break
    return f
if __name__ == '__main__':
    f=(find_num())
    for i in f:
        print(i)

牛客的通过率是73.33%,时间复杂度是O(n*n),所以通过率不是100%。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值