给定一个十进制正整数N,写下从1开始到N的所有整数,然后计算其中出现1的个数。
例如:
N = 2,1到N的所有整数为1,2。这里出现一个’1‘.
N = 12,有1到N的所有整数为1,2,3,4,5,6,7,8,9,10,11,12。这里出现 ’1‘,‘10’,’11‘,’12‘一共5个1。
解法 1
暴力解法:直接遍历1到N中的数。
def Count1InInteger(num):
count = 0
while num:
count += 1 if num%10 == 1 else 0
num //= 10
return count
N = int(input())
icount = 0
for i in range(1,N+1):
icount += Count1InInteger(i)
print(icount)
解法 2
使用规律来进行求解,就拿12013的百位来进行讲解:
如果百位为0,则百位出现1的个数等于(12)更高位数当前位数(100)。
如果百位为1,则百位出现1的个数等于(12)更高位数当前位数(100)+ 更低位数 (13)+ 1
如果百位大于1,则百位出现1的个数等于(13)(更高位数+1)当前位数(100)。
n = int(input())
iCount, iFactor = 0, 1
iLowerNum, iurrNum, iHightNum = 0, 0, 0
while n/iFactor:
iLowerNum = n - (n//iFactor)*iFactor
iCurrNum = (n//iFactor)%10
iHightNum = n//(iFactor*10)
if iCurrNum == 0:
iCount += iHightNum*iFactor
elif iCurrNum == 1:
iCount += iHightNum*iFactor + iLowerNum + 1
else:
iCount += (iHightNum +1)*iFactor
iFactor *= 10
print(iCount)
扩展
对于二进制
f(1) = 1
f(10) = 10 (因为01,10有两个1)
f(11) = 100 (因为01,10,11有四个1)
自己推测的规律还没有验算只是手动推了一下:
当前位为0时,出现1的个数等于高位乘当前位数
当前位为0时,出现1的个数等于高位乘当前位数+低位+1