码迷,mamicode.com
首页 > 其他好文 > 详细

uva 11038

时间:2015-01-15 23:30:26      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:

Problem E: How many 0‘s?

A Benedict monk No. 16 writes down the decimal representations of all natural numbers between and including m and n, m ≤ n. How many 0‘s will he write down?

Input consists of a sequence of lines. Each line contains two unsigned 32-bit integers m and n, m ≤ n. The last line of input has the value of mnegative and this line should not be processed.

For each line of input print one line of output with one integer number giving the number of 0‘s written down by the monk.

Sample input

10 11
100 200
0 500
1234567890 2345678901
0 4294967295
-1 -1

Output for sample input

1
22
92


大意:

给出若干区间 [L, R] 求出将 L~ R 之间的数全部写出来要用多少个 ‘0‘ ?

思路:

数学特别渣....于是决定现在开始版切掉 lrj 的数学专题....

第一个思想就是采用减法间接计算, 不直接计算.

第二个思想就是分类统计....

  把这个数字分开成三段考虑.

  left, i, right. (left != 0)

  如果 i >= 0, 那么不难想到, 这一位上的 0 出现了 10right.len * left 次.(len 表示 right 有几位)

  如果 i == 0, 那么第 i 位的贡献是: 10right.len * (left - 1) + right 次.

  由于不同的位上互不影响,所以用加法原理加起来就 ok 了.

代码应该还能精简一点.

技术分享
 1 #include<cstdlib>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<iostream>
 5 using namespace std;
 6 typedef long long ll;
 7 ll n,m;
 8 ll ans(ll x){
 9     ll t = 1,cnt = 0,tmp = x;
10     while(tmp){        
11         cnt += max((x / (t * 10) - (tmp % 10 == 0)) * t,0LL);
12         if(tmp % 10 == 0) cnt += x % t + 1;
13         t *= 10, tmp /= 10;
14     }
15     return cnt;
16 }
17 int main()
18 {
19     freopen("0.in","r",stdin);
20     freopen("0.out","w",stdout);
21     while(cin >> n >> m, m > 0){
22         ll a = ans(m), b = ans(n-1), c = n == 0;
23         cout << a - b + c << endl;
24     }
25     return 0;
26 }
View Code

 

uva 11038

标签:

原文地址:http://www.cnblogs.com/Mr-ren/p/4227394.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!