题目:
现在有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%。