'''
    输入一个整数 n ，求1～n这n个整数的十进制表示中1出现的次数。
'''
'''
    数学题  分别对每个位置的 1出现的次数求解 然后加起来。
    求解公式：
    个位 ： (n/10)*1 + (n%10 !=0)
    两种情况 1 n<10 所以 n/10 = 0 (n%10!=0) = 1 结果：0+1 = 1
    2 n>10 n/10 表示 十位的大小 是个位的高位 必然会出现 21 31 这些个位含1数
    这样的数一共有 n/10 个 然后 加上 n<10的 情况 
    例如 40 就有 40/10 + 0 个个位为1 的数 01，11，21，31 而 41 则 41/10 + 1 个 多了一个41
    十位 : (n/100)*10 + min(max((n%100 - 10 +1), 0), 10)
    道理和个位类似 三种情况
    1. n%100 <10 则个数为 (n/100)*10 + 0
    2. n%100 >=10 且 <20 则个数为 (n/100)*10 + n%100 - 10 + 1
    3. n%100 >=20 则个数为 (n/100)*10 + 10
    百位 ， 千位都如十位一致的逻辑  h代表高位 c代表此位 如 十位 则 c=10 h = 100
    综合  --  个数为 n/h * c + min(max((n%h-c+1),0),c) 
'''
class Solution:
    def countDigitOne(self, n: int) -> int:
        res = 0
        cur = 1
        while cur <= n:
            divd = cur * 10
            res += (n // divd) * cur + min(max((n % divd - cur + 1), 0), cur)
            cur *= 10
        return res


S = Solution()
print(S.countDigitOne(21345))