最近变懒了。。。很不想写解题报告。。不想写博客。。。
今天又做了一道以前做过类似的枚举题的,可惜忘记了,不会推了,推了大半天,还看下以前的代码。。表示很戳。。。很弱。。。
http://acm.pku.edu.cn/JudgeOnline/problem?id=3286
题意给定区间,求出区间(n,m)里面0 的个数。。。
想法:分别算出<=n g(n),<=m g(m)的个数 , 然后枚举n里面0的个数,答案就是g(m) - g(n) +n里面0的个数。
问题关键:如何求<= m的数,现在我们把m拆开来看,从数的末尾枚举m的每一位,那么枚举第i位的时候,第0~i-1位的数记为left,第i+1~最后 的 数字记为right;此时查看第i位:
1 若此为本身为 0 , 就是说原数字里面本身有一个0 , 然后求出比 ----0------小的数+1 加至 sum ;
2 若次数不为0,则原数该位没0,那么显然小余----0-----的数都是小于原数的, 算出 加至 sum ;
重复以上两个过程,直至left < 10 ;
比如:求小于等于 5010 的0的个数;
设digit为第i位的数字;
sum = 1;
1 枚举第4 位时,left = 501 , right = 0 ,digit = 0 ;
显然 500 0 , 499 0 , 498 0 , …… …… ,3 0 , 2 0, 1 0 ; 都是<5010 的 ,然后+5010 中的最后一个0;
sum += (left - 1)*10^0 + right + 1 = 502 ;
2 枚举第2位时,left = 50 , right = 10 , digit = 1 ;
显然 50 0 X , 49 0 X, 48 0 X, ………… 2 0 X, 1 0 X ; 显然都是 < 5010 的 ; 其中 X =0 ,1,2,3,4,5,6,7,8,9;
sum += left *10 ;
依照上面的循环下去即可。。。
表示这种模型 要记住了。。不能在忘了。。。希望写篇blog能加深印象。。。
代码: