#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
/*
这道题写的自己差点吐血,真是服了,差点放弃
1.前导0 记录直接zero&&i==0,就好了,只不过,没想到他在后面的记忆化中,没有注意
导致0的数量一直都是少的,我们一开始统计的都是没有前导0的,可是后面只要
补上一个数,就会出现比之前多余的0,所以也要记录一下
2.树形模型 其实就是状态压缩么,要不怎么会节约时间呢
3.dp[pos][bit] 没有limit的情况下,在pos最大为bit的情况下的总数量,要理解数组的含义
*/
int pow_(int base,int n){
int ans=1;
for(int i=1;i<=n;i++)
ans*=base;
return ans;
}
int dp[10][10][10];
int cnt;
int bit[10];
int get_num(int pos){
int ans=0;
for(int i=pos-1;i>=0;i--){
ans=ans*10+bit[i];
}
return ans;
}
int dfs(int pos,int limit,int val,int zero,int bb){//当前数字取某一个特定的值
if(pos==-1){//0的特殊之处
if(zero&&bb==0)return 1;//如果是0的数量
return 0;
}
if(!limit&&!zero&&dp[pos][val][bb]!=-1){
return dp[pos][val][bb];
}
int max_num=limit?bit[pos]:9;
int sum=0;//计算 在当前最大值为val的前提下,特定数字的总数量!!!
for(int i=0;i<=max_num;i++){
if(zero&&i==0)
;
else if(i==bb){//统计当前位就是 需要的值
if(limit&&i==max_num)
sum+=get_num(pos)+1;
else
sum+=pow_(10,pos);
}
sum+=dfs(pos-1,limit&&i==max_num,i,zero&&(i==0),bb);//统计下面所有层的总和
}
if(!limit&&!zero)dp[pos][val][bb]=sum;//当前位置为最大值 val的前提下,特定数字的总数量!!!前导0
return sum;
}
int ans1[10],ans2[10];
void solve(int num,int flag){
cnt=0;
while(num){
bit[cnt++]=num%10;
num/=10;
}
if(flag){
for(int i=0;i<10;i++)ans1[i]=dfs(cnt-1,1,bit[cnt-1],1,i);
}
else{
for(int i=0;i<10;i++)ans2[i]=dfs(cnt-1,1,bit[cnt-1],1,i);
}
}
/*
1 10
44 497
346 542
1199 1748
1496 1403
1004 503
1714 190
1317 854
1976 494
1001 1960
0 0
*/
int main()
{
memset(dp,-1,sizeof(dp));
int a,b;
while(scanf("%d %d",&a,&b)==2){
if(a==0&&b==0)break;
if(a>b)swap(a,b);
solve(b,1);
solve(a-1,0);
for(int i=0;i<10;i++){
if(i==0) printf("%d",ans1[i]-ans2[i]);
else printf(" %d",ans1[i]-ans2[i]);
}
printf("\n");
}
return 0;
}
The Counting Problem UVA - 1640
最新推荐文章于 2020-04-19 21:29:12 发布