Python中求从1到n正整数中1的个数
时间: 2024-01-28 15:05:33 浏览: 94
可以使用数学归纳法证明,对于一个数n,可以将它拆分成n = a * 10^i + b,其中a是n的最高位数字,b是除最高位数字外剩余的部分。
如果a = 0,则n的最高位数字为0,此时1的个数为:
f(n) = f(b)
如果a = 1,则n的最高位数字为1,此时1的个数为:
f(n) = f(b) + (b + 1)
如果a > 1,则n的最高位数字大于1,此时1的个数为:
f(n) = a * f(10^i-1) + 10^i
其中f(10^i-1)表示从1到10^i-1的所有数字中1的个数。
根据以上递推公式,可以写出Python程序求解从1到n正整数中1的个数:
```python
def count_one(n):
if n <= 0:
return 0
s = str(n)
high = int(s[0]) # 最高位数字
pow10 = 10 ** (len(s) - 1) # 10的幂次方
last = n - high * pow10 # 除最高位数字外剩余部分
if high == 1:
return count_one(pow10 - 1) + count_one(last) + last + 1
else:
return high * count_one(pow10 - 1) + pow10 + count_one(last)
```
例如,count_one(120)的结果为93,表示从1到120中1的个数为93个。
相关问题
用python怎么做.从1到n整数中1的个数 类型: 字符串 描述 输入一个正整数n,求出1~n的整数中1出现的次数, 求出任意非负整数区间中1出现的次数(从1到n中1出现的次数) 输入格式 输入一个正整数n 输出格式 输出1的个数
可以通过遍历1到n的每一个数字,然后将数字转换为字符串,再遍历字符串中的每一位,判断是否为'1',如果是则计数器+1。最后返回计数器的值即可。
以下是代码实现:
```python
def count_one(n):
count = 0
for i in range(1, n + 1):
str_i = str(i)
for char in str_i:
if char == '1':
count += 1
return count
```
如果要求任意非负整数区间中1出现的次数,可以将上述代码稍作修改,通过传入区间的起始和结束数字,只遍历该区间内的数字即可。
```python
def count_one_range(start, end):
count = 0
for i in range(start, end + 1):
str_i = str(i)
for char in str_i:
if char == '1':
count += 1
return count
```
需要注意的是,这种方法在遍历每个数字的每一位时,时间复杂度是O(d*n),其中d是数字的位数,n是数字的数量。因此,当数字很大时,这种方法可能会超时。在这种情况下,可以考虑其他更高效的算法,比如数位DP等。
题目描述 给定一个正整数n(n<=10^9),计算所有小于等于n的正整数中数字1出现的个数。 关于输入 正整数 n(n<=10^9) 关于输出 所有小于等于n的正整数中数字1出现的个数
这是一个经典的数位统计问题。我们可以使用数位动态规划(Digit Dynamic Programming)来解决这个问题。以下是解决思路和实现方法:
1. 状态定义:
dp[i][j][k] 表示考虑前i位数字,当前位数字是j,是否已经达到上限(k=0表示未达到,k=1表示已达到)的1的个数。
2. 状态转移:
根据当前位数字和是否达到上限,分情况讨论并累加1的个数。
3. 初始化:
dp[0][0][0] = 0
4. 最终答案:
dp[len][0][1],其中len是n的位数。
下面是Python代码实现:
```python
def count_ones(n):
s = str(n)
len_s = len(s)
dp = [[[0] * 2 for _ in range(10)] for __ in range(len_s + 1)]
dp[0][0][0] = 0
for i in range(len_s):
for j in range(10):
for k in range(2):
if k == 1:
upper = int(s[i])
else:
upper = 9
for digit in range(0, upper + 1):
new_k = k or (digit < upper)
dp[i + 1][digit][new_k] += dp[i][j][k]
if digit == 1:
dp[i + 1][digit][new_k] += 10 ** (len_s - i - 1)
if j == 1:
dp[i + 1][digit][new_k] += j * (10 ** (len_s - i - 1))
return dp[len_s][0][1]
# 测试
n = int(input())
print(count_ones(n))
```
这个算法的时间复杂度是 O(len_s * 10 * 2) = O(len_s),其中len_s是数字n的位数。由于n最大为10^9,所以len_s最大为10,因此这个算法是高效的。
阅读全文
相关推荐













