数位DP
count:从1-n,x(从0-9)出现了多少次
分两种情况讨论(详见YXC)
此位为中间位:
此位之前的总数乘上次位之后的组合数(10^位数)
此位为最高位:
x小于此位
大于
等于此位
当x=0时特别讨论
注意输入时a,b的大小
时间复杂度:O(常数)*输入
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cmath>
using namespace std;
vector<int> input_1;
vector<int> input_2;
int get(vector<int> num,int r,int l){
int n=0;
for(int i=r;i>=l;i--){
n*=10;
n+=num[i];
}
return n;
}
int count(int n,int x){
if(!n) return 0;
vector<int> num;
while(n){
num.push_back(n%10);
n/=10;
}
n = num.size();
int res = 0;
for(int i=n-1;i>=0;i--){
if(x==0){
res+=(get(num,n-1,i+1)-1)*pow(10,i);
if(num[i]==0) res+=get(num,i-1,0)+1;
else if(num[i]>0) res+=pow(10,i);
}else{
res+=(get(num,n-1,i+1))*pow(10,i);
if(num[i]<x) res+=0;
else if(num[i]==x) res += get(num,i-1,0)+1;
else if(num[i]>x) res+=pow(10,i);
}
}
return res;
}
int main(){
int a,b;
while(cin>>a>>b,a||b){
input_1.push_back(min(a,b));
input_2.push_back(max(a,b));
}
// for(int i=1199;i<=1199;i++){
// for(int j=0;j<=9;j++) cout<<i<<":"<<count(i,j)<<" ";
// cout<<endl;
// }
// for(int i=1748;i<=1748;i++){
// for(int j=0;j<=9;j++) cout<<i<<":"<<count(i,j)<<" ";
// cout<<endl;
// }
for(int i=0;i<input_1.size();i++){
for(int j=0;j<=9;j++){
cout<<count(input_2[i],j)-count(input_1[i]-1,j)<<" ";
}
cout<<endl;
}
}