刚看到此问题的第一印象就是一个纯粹的数学问题。
问题分析
从问题描述来看,针对于每一个数位上‘1’的统计都有着规定的规律,例如:
对于n=1234,为了统计其十位上‘1’的数目,可以很清晰的发现对于[00,99]后两位数字在这个的区间内,十位上‘1’的数目为10,此类似区间中‘1’的数目都为10。类似区间的长度都为100,这是很重要的点。
计算n=1200十位包含‘1’数目的公式如下:,而对于n十位和个位留下的数中包含十位‘1‘数目,需分情况进行讨论:d=n mod 100
如果d<10,则十位包含’1‘数目为0;
如果d>=20,则十位包含'1'数目为10;
如果d处于[10,19]间,则十位包含'1'数目为d-10+1;
针对于其他数位而言有相同的情况。
问题解决和代码关键点(枚举)
因此,按照上述处理方式利用循环来进行枚举,计算所有’1‘的数目。
循环条件:从个位到高位依次进行处理,条件为n>=10*num,num代表着所计算的位数。
循环体:p1=n/(10*num),(代表的是满足完整的位数上循环区间的’1‘的数目)上面例子第一部分
d=n%(10*num), p2=min(max(0,(d-10*(num-1))+1),10*(num-1))
max保证了一个上述例子中d<10,左区间限制条件,min保证了右区间限制条件。
循环到最高位时,完成计算。
注意:
采用的数据结构为long long int,保证能存储的最大数目。
0LL表示数据类型为long long int的0整型。