一、题目
给定两个整数 a 和 b,求 a 和 b 之间的所有数字中 0∼9的出现次数。
例如,a=1024,b=1032,则 a 和 b 之间共有 9个数如下:
1024 1025 1026 1027 1028 1029 1030 1031 1032
其中 0 出现 10次,1 出现 10 次,2 出现 7 次,3 出现 3次等等…
输入格式
输入包含多组测试数据。
每组测试数据占一行,包含两个整数 a和 b。
当读入一行为 0 0 时,表示输入终止,且该行不作处理。
输出格式
每组数据输出一个结果,每个结果占一行。
每个结果包含十个用空格隔开的数字,第一个数字表示 0 出现的次数,第二个数字表示 1 出现的次数,以此类推。
数据范围
0<a,b<100000000
输入样例:
1 10
44 497
346 542
1199 1748
1496 1403
1004 503
1714 190
1317 854
1976 494
1001 1960
0 0
输出样例:
1 2 1 1 1 1 1 1 1 1
85 185 185 185 190 96 96 96 95 93
40 40 40 93 136 82 40 40 40 40
115 666 215 215 214 205 205 154 105 106
16 113 19 20 114 20 20 19 19 16
107 105 100 101 101 197 200 200 200 200
413 1133 503 503 503 502 502 417 402 412
196 512 186 104 87 93 97 97 142 196
398 1375 398 398 405 499 499 495 488 471
294 1256 296 296 296 296 287 286 286 247
二、解答
若有整数abcdefg,现在要找0-abcdefg中m的个数,可以分别找第i位为m的个数,即形如xxxmxxx的数的个数。,最后再相加。
这里假设g为第0位,f为第1位…
eg:
首先用一个例子,即找第[3]位即d所在位置为x的个数(其它位的将[]中的数字替换)
分情况讨论,分为4类:(实际只用讨论3类)
第一类: 最高位小于abc,即从0到abc-1
则最高三位有abc种可能,后三位(即efg所在)有999-000+1=1000种可能,即10的[3]次方种可能
第二类:最高位等于abc,且d>x
则后三位可以从000取到999,即10的[3]次方种可能
第三类: 最高位为abc,且d=x
则后三位只能从000取到efg,则有efg+1种可能
第四类: 最高位为abc,且d<x
有0种可能(所以这一类不用讨论)
!!!注意:
当x为0,即要找0的个数时,需要考虑到0的前面不能都是0,这样的数是不合法的(如要找第3位是0的数,则该数不能为0000123,而只能是类似10123,即0的前面至少要有一个非0的数)
所以如果x=0,则最高位不能为000,只能从001开始,取到abc,共有abc-1个
三、代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
//从容器a中获取l到r的数,如从12345获取0-2的数为123
int get(vector<int> a,int l,int r){
int res=0;
for(int i=r;i>=l;i--){
res=res*10+a[i];
}
return res;
}
//求10的a次方
int power10(int a){
int res=1;
while(a--) res*=10;
return res;
}
//输出0-a的数中x的个数
int cnt(int a,int x){
if(!a) return 0;//特判,如果a=0,则直接返回0
int size=0;
vector<int> v;
while(a){
v.push_back(a%10);
size++;
a/=10;
}
int sum=0;
//求x在第i个位置的个数
for(int i=0;i<size-!x;i++){
sum+=get(v,i+1,size-1)*power10(i);
if(i<size-1&&!x) sum-=power10(i);//如果是0,则高位不能都是0,要从001开始计算,故上一步的get值要减一
if(v[i]==x) sum+=get(v,0,i-1)+1;
else if(v[i]>x) sum+=power10(i);
}
return sum;
}
int main(){
int a,b;
cin>>a>>b;
while(!(a==0&&b==0)){
if(a<b) swap(a,b);
for(int i=0;i<=9;i++){
cout<<cnt(a,i)-cnt(b-1,i)<<" ";
}
cout<<endl;
cin>>a>>b;
}
return 0;
}