这道题思路有两种,一种是数位DP,一种就是排列组合,这道题我用的是排列组合。
大致题意,用样例来说,1到7中,1的个数为2的有多少
0 | 0 0 0
1 | 0 0 1
2 | 0 1 0
3 | 0 1 1
4 | 1 0 0
5 | 1 0 1
6 | 1 1 0
7 | 1 1 1
由此可看出来有3个,分别是3(011),5(101),6(110)。
对于二进制7来讲,我们可以分为三个区间进行排列组合,(111,110],(110,100],(100,000]。对于第一个区间,没有可以组合的方式,对于第二个区间只有一种组合的方式101,对于第三个区间也是只有一种011。
def C(a,b): #组合排列
ans=1
for i in range(1,b+1):
ans = int(ans * a / i)
a-=1
return ans
def getLen(x): #求一个数转二进制后的长度,以及其中1的个数
cnt,cnt1=0,0
while x:
if x&1:
cnt1+=1
x>>=1
cnt+=1
return cnt,cnt1
def lowbit(x): #lowbit函数求出二进制数中最后的1
return x&-x
N,K=map(int,input().split())
NLen,OneLen=getLen(N)
ans = 0
if OneLen == K: ans += 1 #因为我们的左区间是开区间,所以N需要特判
b=K-OneLen #有多少个位置可以填,111不仅没有,而且还多出一位所以为-1
while N:
x=lowbit(N)
N-=x
b+=1
a=getLen(x)[0]-1
if b>=0:
ans+=C(a,b) #加上每一个区间符合条件的数量
print(ans)
版权声明:本文为m0_63485850原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。