Uva1640(统计数字出现的次数)

Posted romalzhih

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Uva1640(统计数字出现的次数)相关的知识,希望对你有一定的参考价值。

题意:

统计两个整数a,b之间各个数字(0~9)出现的次数,如1024和1032,他们之间的数字有1024 1025 1026 1027 1028 1029 1030 1031 1032 总共有10个0,10个1,3个3等等。

解法:

这类问题的一般步骤都是先用f(n,d)计算出0~n中d数字出现的次数,那么答案就是f(b,d)-f(a-1,d)

下面程序中的注释为(1,2974)的第一层(未递归)解释,递归后同理

1-2974 拆分为1-2970  和 2971-2974

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 int l, r;
 6 int a[11], b[11];
 7 
 8 void solve(int n, int m) {
 9     int x = n / 10;//除了末位以外的                     x=297
10     int y = n % 10;//最后一位的数字范围                  y=4
11     int tmp = x;
12     //计算小于10*x+1到10*x+y中个位数的个数,b[1-y]也就是(2971-2974)个位数
13     for (int i = 1; i <= y; i++)b[i] += m;
14     //计算10*x-10到10*x-1中个位数的总个数,296 0-296 9 个位数个数每个都是296个
15     for (int i = 0; i <= 9; i++)b[i] += m*x;
16     while (tmp) {
17     //10*x 到10*x+y非个位的个数,因为从0开始,所以*(y+1)就是非个位位数,当然还要乘m
18         b[tmp % 10] += m*(y + 1);     
19         tmp /= 10;
20     }
21     if (x) solve(x - 1, m * 10);
22 }
23 
24 int main() {
25     while (cin >> l >> r && (l || r)) {
26         memset(b, 0, sizeof(b));
27         if (l > r)swap(l, r);
28         solve(l - 1, 1);
29         for (int i = 0; i <= 9; i++)a[i] = b[i], b[i] = 0;
30         solve(r, 1);
31         cout << b[0] - a[0];
32         for (int i = 1; i <= 9; i++)cout << " " << b[i] - a[i];
33         cout << endl;
34     }
35     return 0;
36 }

 

以上是关于Uva1640(统计数字出现的次数)的主要内容,如果未能解决你的问题,请参考以下文章

UVA 1640 The Counting Problem

UVa 1640 - The Counting Problem(数论)

UVA 1225 Digit Counting(统计数位出现的次数)

UVA11038

[uva11235]Frequent values(RMQ,ST,离散化)

UVa 11100 旅行2007