解题过程的小记录,如有错误欢迎指出。
难度:四星(找规律题,宛若奥赛,找到规律后程序倒是很简短)
给出一个数,找出<=这个数的所有含有1的数,并且计算出现的1的次数
11是含有1的数,且含有2个1,需要在结果中累加2,并不是找出所有含有1的数字的个数
给出一个数n,例30710,按照从高位到低位对其进行编号(3-1号,0-2号,7-3号,1-4号,0-5号),找出不同号上的位数对结果的影响,设now表示当前指向的号码对应的数字,left表示所指向数字左边的数字,right表示所指向的数字右边的数字,并设置一个变量 a(初始化为1,每次向高一位递增时a累乘10)
当指向1号时 1号所对应的数字是0,当它为1时,left的范围必须是0000~3070(共计3071个),若为3071则生成的数字为30711,超过了n的范围当指向2号时 2号所对应的数字是1,此时a为10,left=307,right=0,当now取1时,left可以取000 ~ 306对应right取0 ~ 9(10个),当left取307时,right只能取0当指向3号时 3号所对应的数字是7,此时a为100,left=30,right=10,当now取1时,left可以取00 ~ 30,对应right取00 ~ 99(100个)当指向4号时 4号所对应的数字是0,此时a=1000,left=3,right=710,当now取1时,left可以取0 ~ 2,对应right取000 ~ 999(1000个),right取3时,now就不可能为1所以没用当指向5号时 5号所对应的数字是3,此时a=10000,left=0710,当now取1时,left可以取0000 ~ 9999(10000个)通过以上可以看出当now指向0/1时与其他状态不同,所以要特殊讨论,通过数字看出now,left,right和a的关系,得出 当now=0时,ans += left * a, 当now=1时,ans += left * a + right +1, 当now>=2时,ans += (left + 1)*a
要考虑边界点的输出,如1,7
全部代码因版权原因不放出来,大家可以自行去柳神博客购买或者参考晴神的上机笔记~
还可以通过a来除和求余n来得到now,left和right
left = n / (a * 10), now = n / a % 10, right = n % a;