The task is simple: given any positive integer N, you are supposed to count the total number of 1's in the decimal form of the integers from 1 to N. For example, given N being 12, there are five 1's in 1, 10, 11, and 12.
Input Specification:
Each input file contains one test case which gives the positive N (≤230).
Output Specification:
For each test case, print the number of 1's in one line.
Sample Input:
12
Sample Output:
5
-------------------------------------这是题目和解题的分割线-------------------------------------
暴力会超时,所以要找规律。我是没找出来,参考的书上思路QAQ
总共分为三种情况:
①当前位数字为0,那么1的个数由高位的数字确定。
②当前位数字为1,那么1的个数由高位数字和低位数字共同确定。
③当前位数字大于1,那么1的个数由高位数字确定。
它们都和高位数字相关,所以可以在判断是以上哪种情况之前,先加上基本次数。
举个例子,213,先看个位数,3>1,则个位数出现1的次数为21*10^0(基本次数)+10^0(情况③)=22
再看十位数,1==1,则十位数出现1的次数为2*10^1(基本次数)+(213%10^1)+1(情况②) = 24
(213%10^1+1是低位数,n%10^x是求得低位数,+1是加上本身位数的1)
最后是百位数,2,同理个位数,出现的次数为2,没有高位数也就没有基本次数,10^2 = 100
所以最后是 22+24+100 = 146。
ps:①情况只需要算基本次数,因为是0,当每个位置都有数字的时候,不可能出现1。
#include<stdio.h>
int main()
{
int num,count = 0,p = 1;
scanf("%d",&num);
int tmp = num;
while(tmp)
{
//基本次数
count += tmp/10*p;
//如果该位值的数大于1
if(tmp%10>1)
count += p;
//低位数+自身
else if(tmp%10==1)
count += num%p+1;
tmp /= 10;
//p记录位数
p *= 10;
}
printf("%d",count);
return 0;
}
本文介绍了一种高效算法,用于计算从1到任意正整数N中所有数字中1的总数。通过分析数字的不同位数,算法将计算过程分为三种情况,并利用高位数字来快速确定1的出现次数。示例代码展示了如何实现这一算法。
1021

被折叠的 条评论
为什么被折叠?



