需要分类讨论:
1.首先按每一位进行分类计算
2.位左边的分类为小于与相等两类:
2.1 小于:直接乘10的右边位数次方
2.2 等于:按取的呢一位进行分类讨论:
设本来的呢一位上的数字为d,所求的为x
2.2.1 若 d == x,则总和加右边数量+1
2.2.2 若 d > x,则总和加10的右边位数次方
3.取第一位时需要单独判断
4.d为0时需要单独判断右边,从xxxx1开始,故2.1中的情况要少一种000…0dxxx,所以乘数-1
总结:总的来说理解思路并不难,就是情况太多了容易漏,代码实现时候容易写错出bug
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 10;
int get(vector<int>n,int a,int b){
int res = 0;
for(int i =a;i>=b;i--)
{
res=res*10+n[i];
}
return res;
}
int power10(int x)
{
int res = 1;
for(int i = 0;i<x;i++)
res*=10;
return res;
}
int cnt(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-!x;i>=0;i--)
{
if(i<n-1)
{
res+= get(num,n-1,i+1) * power10(i);
if(!x) res-=power10(i);
}
if(num[i] == x)res+=get(num,i-1,0)+1;
else if(num[i]>x) res+=power10(i);
}
return res;
}
int main(){
int a,b;
while(cin>>a>>b,a||b)
{
if(a>b)swap(a,b);
for(int i =0;i<=9;i++)
cout<< cnt(b, i) - cnt(a-1,i)<<' '; //注意这里是到a-1,与前缀合类似
cout<<endl;
}
return 0;
}