3519.统计逐位非递减的整数
难度:困难
问题描述:
给你两个以字符串形式表示的整数l和r,以及一个整数b。返回在区间[l,r](闭区间)内,以b进制表示时,其每一位数字为非递减顺序的整数个数。
整数逐位非递减需要满足:当按从左到右(从最高有效位到最低有效位)读取时,每一位数字都大于或等于前一位数字。
由于答案可能非常大,请返回对109+7取余后的结果。
示例1:
输入:l="23",r="28",b=8
输出:3
解释:
从23到28的数字在8进制下为:27、30、31、32、33和34。
其中,27、33和34的数字是非递减的。因此,输出为3。
示例2:
输入:l="2",r="7",b=2
输出:2
解释:
从2到7的数字在2进制下为:10、11、100、101、110和111。
其中,11和111的数字是非递减的。因此,输出为2。
提示:
1<=l.length<=r.length<=100
2<=b<=10
l和r仅由数字(0-9)组成。
l表示的值小于或等于r表示的值。
l和r不包含前导零。
问题分析:
为解决10进制以上的进位制数码不足的问题,我们在处理数码时超过9的数码直接用10进制数描述,比如16进制的数码就分别是0......10、11、12、13、14、15,但这些数码如果组成一个16进制数又难以分辨清楚,所以在转换的时候,我们把各位数码按顺序放在一个列表中,既清楚各位数码的位置,又方便比较大小,可谓是一个很好的处理方法。
总的来说,解决这个问题,涉及到这样一些问题的解决:
- 如何将一个10进制数转换为b进制数?
为此编制了一个函数change_x_b(x,b),其功能是将一个10进制数x转换为b进制数,采用的是除b取余法,将转换得到的各位数码存放在列表result中,最后返回这个列表。
- 编制函数is_not_decreasing_num(a),其功能是判断一个b进制数是否为一个非逐位递减的整数,只不过这个数的呈现方式是一个列表a,其元素由这个b进制数的各位数码组成,如果a中元素是非递减的,返回True,否则返回False。
- 设计函数get_no_decreasing_count(l,r,b),其功能是统计从字符串形式的十进制数l到r中,有多少个b进制数是非逐位递减的整数。其实现是用一个从10进制数l到r的循环依次取其中的每一个数,转换成对应的b进制数数码列表,再判断这个列表是不是非递减的整数序列,如果是,则计数,否则取下一个继续这样做,最后返回非递减整数序列的个数即是问题的解。
程序如下:
#将一个十进制整数x转换为b进制数,返回一个转换成b进制数的数码列表
def change_x_b(x,b):s=x//b #s表示商y=x%b #y表示余数result=[y]while s!=0:x=ss=x//by=x%bresult.append(y)return result[::-1]#判断一个b进位制数的数码组成的列表a是否为非递减的,如果是,返回True,否则返回False
def is_not_decreasing_num(a):n=len(a)for i in range(n-1):if a[i+1]<a[i]:return Falseelse:continueelse:return True#对输入的l和r以及b进行处理,统计逐位非递减整数数量并返回
def get_no_decreasing_count(l,r,b):l=int(l)r=int(r)c=0for i in range(l,r+1):k=change_x_b(i,b)print(f'10进制数{i}',f'转换为{b}进制数之后生成的数码列表{k}')if is_not_decreasing_num(k):c=c+1print(f'符合非递减条件,当前共有{c}个逐位非递减{b}进制整数')return c#主程序
l=input('pls input l=')
r=input('pls input r=')
b=int(input('pls input b='))
n=get_no_decreasing_count(l,r,b)
print(f'从10进制数{l}到{r}的{b}进制整数中,共有逐位非递减整数共{n}个')
运行实例1
pls input l=10
pls input r=18
pls input b=7
10进制数10 转换为7进制数之后生成的数码列表[1, 3]
符合非递减条件,当前共有1个逐位非递减7进制整数
10进制数11 转换为7进制数之后生成的数码列表[1, 4]
符合非递减条件,当前共有2个逐位非递减7进制整数
10进制数12 转换为7进制数之后生成的数码列表[1, 5]
符合非递减条件,当前共有3个逐位非递减7进制整数
10进制数13 转换为7进制数之后生成的数码列表[1, 6]
符合非递减条件,当前共有4个逐位非递减7进制整数
10进制数14 转换为7进制数之后生成的数码列表[2, 0]
10进制数15 转换为7进制数之后生成的数码列表[2, 1]
10进制数16 转换为7进制数之后生成的数码列表[2, 2]
符合非递减条件,当前共有5个逐位非递减7进制整数
10进制数17 转换为7进制数之后生成的数码列表[2, 3]
符合非递减条件,当前共有6个逐位非递减7进制整数
10进制数18 转换为7进制数之后生成的数码列表[2, 4]
符合非递减条件,当前共有7个逐位非递减7进制整数
从10进制数10到18的7进制整数中,共有逐位非递减整数共7个
运行实例2
pls input l=20
pls input r=33
pls input b=16
10进制数20 转换为16进制数之后生成的数码列表[1, 4]
符合非递减条件,当前共有1个逐位非递减16进制整数
10进制数21 转换为16进制数之后生成的数码列表[1, 5]
符合非递减条件,当前共有2个逐位非递减16进制整数
10进制数22 转换为16进制数之后生成的数码列表[1, 6]
符合非递减条件,当前共有3个逐位非递减16进制整数
10进制数23 转换为16进制数之后生成的数码列表[1, 7]
符合非递减条件,当前共有4个逐位非递减16进制整数
10进制数24 转换为16进制数之后生成的数码列表[1, 8]
符合非递减条件,当前共有5个逐位非递减16进制整数
10进制数25 转换为16进制数之后生成的数码列表[1, 9]
符合非递减条件,当前共有6个逐位非递减16进制整数
10进制数26 转换为16进制数之后生成的数码列表[1, 10]
符合非递减条件,当前共有7个逐位非递减16进制整数
10进制数27 转换为16进制数之后生成的数码列表[1, 11]
符合非递减条件,当前共有8个逐位非递减16进制整数
10进制数28 转换为16进制数之后生成的数码列表[1, 12]
符合非递减条件,当前共有9个逐位非递减16进制整数
10进制数29 转换为16进制数之后生成的数码列表[1, 13]
符合非递减条件,当前共有10个逐位非递减16进制整数
10进制数30 转换为16进制数之后生成的数码列表[1, 14]
符合非递减条件,当前共有11个逐位非递减16进制整数
10进制数31 转换为16进制数之后生成的数码列表[1, 15]
符合非递减条件,当前共有12个逐位非递减16进制整数
10进制数32 转换为16进制数之后生成的数码列表[2, 0]
10进制数33 转换为16进制数之后生成的数码列表[2, 1]
从10进制数20到33的16进制整数中,共有逐位非递减整数共12个
运行实例3
pls input l=5
pls input r=10
pls input b=2
10进制数5 转换为2进制数之后生成的数码列表[1, 0, 1]
10进制数6 转换为2进制数之后生成的数码列表[1, 1, 0]
10进制数7 转换为2进制数之后生成的数码列表[1, 1, 1]
符合非递减条件,当前共有1个逐位非递减2进制整数
10进制数8 转换为2进制数之后生成的数码列表[1, 0, 0, 0]
10进制数9 转换为2进制数之后生成的数码列表[1, 0, 0, 1]
10进制数10 转换为2进制数之后生成的数码列表[1, 0, 1, 0]
从10进制数5到10的2进制整数中,共有逐位非递减整数共1个
运行实例4
pls input l=70
pls input r=80
pls input b=60
10进制数70 转换为60进制数之后生成的数码列表[1, 10]
符合非递减条件,当前共有1个逐位非递减60进制整数
10进制数71 转换为60进制数之后生成的数码列表[1, 11]
符合非递减条件,当前共有2个逐位非递减60进制整数
10进制数72 转换为60进制数之后生成的数码列表[1, 12]
符合非递减条件,当前共有3个逐位非递减60进制整数
10进制数73 转换为60进制数之后生成的数码列表[1, 13]
符合非递减条件,当前共有4个逐位非递减60进制整数
10进制数74 转换为60进制数之后生成的数码列表[1, 14]
符合非递减条件,当前共有5个逐位非递减60进制整数
10进制数75 转换为60进制数之后生成的数码列表[1, 15]
符合非递减条件,当前共有6个逐位非递减60进制整数
10进制数76 转换为60进制数之后生成的数码列表[1, 16]
符合非递减条件,当前共有7个逐位非递减60进制整数
10进制数77 转换为60进制数之后生成的数码列表[1, 17]
符合非递减条件,当前共有8个逐位非递减60进制整数
10进制数78 转换为60进制数之后生成的数码列表[1, 18]
符合非递减条件,当前共有9个逐位非递减60进制整数
10进制数79 转换为60进制数之后生成的数码列表[1, 19]
符合非递减条件,当前共有10个逐位非递减60进制整数
10进制数80 转换为60进制数之后生成的数码列表[1, 20]
符合非递减条件,当前共有11个逐位非递减60进制整数
从10进制数70到80的60进制整数中,共有逐位非递减整数共11个
还是一句话,将复杂问题分解为多个小问题,并用功能单一的函数实现,就能帮助自己厘清思路,使问题得到解决。