import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
while(true){
int a=sc.nextInt();
int b=sc.nextInt();
if(a==0&&b==0) break;
if(a>b){//保证b>a
int c=a;
a=b;
b=c;
}
for(int i=0;i<10;i++){ //前缀和思路
System.out.print(count(b,i)-count(a-1,i)+" ");
}
System.out.println("");
}
}
static int count(int n,int x){
if(n==0) return 0;
int cnt=0,res=0;
int[] number=new int[10];
while(n>0){
number[cnt++] = n%10; //存每一位
n/=10;
}
n=cnt; //长度就是cnt
if(x==0) cnt=1; else cnt=0; //减去cnt可以保证x=0时从第二位开始算
for(int i=n-1-cnt;i>=0;i--){
//0bcdefg是算成bcdefg ,此时第一位是0是无效次数的,因为第一位的0不计算在答案里
//那么这些无效的次数就等价于从第二位开始算,后面的bcdefg或10^6的次数就不会计算到
if(i<n-1){ //第一位的时候前面不能取到abc-1,会变成负数-1,
res+=get(number,n-1,i+1)*power(i); //000->abc-1的出现次数
if(x==0) res-=power(i); //前缀0不会计算,所以0000efg是无效的一次,所以取001->abc-1
} //加上前面等于abc的时候
if(number[i]==x) res+=get(number,i-1,0)+1;
else if(number[i]>x) res+=power(i);
}
return res;
}
static int get(int arr[],int l,int r){ //arr的区间l-r的数值
int res=0;
for(int i=l;i>=r;i--){
res=res*10+arr[i];
}
return res;
}
static int power(int x){ //10^x次方
int res=1;
while(x>0){
res*=10;
x--;
}
return res;
}
}
二刷复习:
背模板,然后看按位取什么去分析答案,最后累计求和
import java.util.*;
public class Main{
static int N = 10;
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(true){
int a = sc.nextInt();
int b = sc.nextInt();
if(a == 0 && b == 0) break;
if(a > b){
int c = a;
a = b;
b = c;
}
for(int i = 0; i < 10; i ++)
System.out.print(count(b, i) - count(a-1, i) + " ");
System.out.println();
}
}
static long count(int n, int x){
if(n == 0) return 0;
long res = 0;
List<Integer> num = new ArrayList();
while(n > 0){
num.add(n%10);
n /= 10;
}
int cnt = num.size();
for(int i = cnt-1; i >= 0; i --){
if(i == cnt - 1 && x == 0) continue; // 首位不能取0(跳过前缀0)
// 前面取000 ~ abc-1,后面任选, x=0时不能取000
res += get(num, cnt-1, i+1) * pow10(i); // 共 abc * 10^i
if(x == 0) res -= pow10(i); // 当前位是0,那么前缀不能是000, abc * 10^i - 10^i 删去前面000后面任选的方案数
// 前面取abc,且当前位是x
if(num.get(i) == x) res += get(num, i-1, 0) + 1; // 后面只能取 000 ~ efg
else if(num.get(i) > x) res += pow10(i); // 后面取 000 ~ 999
}
return res;
}
static int get(List<Integer> num, int l, int r){ // 区域值
int res = 0;
for(int i = l; i >= r; i --){
res = res * 10 + num.get(i);
}
return res;
}
static int pow10(int x){ // 10次幂
return (int)Math.pow(10, x);
}
}