zoukankan      html  css  js  c++  java
  • bzoj1833 [ZJOI2010]count 数字计数

    Description

    给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。

    Input

    输入文件中仅包含一行两个整数a、b,含义如上所述。

    Output

    输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次。

    Sample Input

    1 99

    Sample Output

    9 20 20 20 20 20 20 20 20 20

    HINT

    30%的数据中,a<=b<=10^6;
    100%的数据中,a<=b<=10^12。

    正解:数位$dp$。

    简单数位$dp$,直接记录每一位的数字个数然后计算答案即可。

     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 
     6 using namespace std;
     7 
     8 struct data{ ll a[10]; }f[15][2],IE;
     9 
    10 int vis[15][2],st[15],top;
    11 ll g[15][2],ans[10],l,r;
    12 
    13 il ll dfs1(RG int pos,RG int lim){
    14   if (!pos) return 1;
    15   if (g[pos][lim]!=-1) return g[pos][lim];
    16   RG int end=lim?st[pos]:9; RG ll res=0;
    17   for (RG int i=0;i<=end;++i)
    18     res+=dfs1(pos-1,lim && i==end);
    19   return g[pos][lim]=res;
    20 }
    21 
    22 il data dfs2(RG int pos,RG int lim){
    23   if (!pos) return IE;
    24   if (vis[pos][lim]) return f[pos][lim]; vis[pos][lim]=1;
    25   for (RG int i=0;i<=9;++i) f[pos][lim].a[i]=0;
    26   RG int end=lim?st[pos]:9;
    27   for (RG int i=0;i<=end;++i){
    28     RG data res=dfs2(pos-1,lim && i==end);
    29     for (RG int j=0;j<=9;++j) f[pos][lim].a[j]+=res.a[j];
    30     f[pos][lim].a[i]+=dfs1(pos-1,lim && i==end);
    31   }
    32   return f[pos][lim];
    33 }
    34 
    35 il void solve(RG ll n,RG int fg){
    36   top=0; while (n) st[++top]=n%10,n/=10;
    37   memset(g,-1,sizeof(g)),memset(vis,0,sizeof(vis));
    38   RG data res=dfs2(top,1);
    39   for (RG int i=top;i;--i) ans[0]-=fg*dfs1(i-1,0);
    40   for (RG int i=0;i<=9;++i) ans[i]+=fg*res.a[i]; return;
    41 }
    42 
    43 int main(){
    44 #ifndef ONLINE_JUDGE
    45   freopen("count.in","r",stdin);
    46   freopen("count.out","w",stdout);
    47 #endif
    48   cin>>l>>r,solve(r,1),solve(l-1,-1),printf("%lld",ans[0]);
    49   for (RG int i=1;i<=9;++i) printf(" %lld",ans[i]); return 0;
    50 }
  • 相关阅读:
    如何打开指定文件所在的文件夹并选中文件
    不阻止多线程中控件跨线程访问
    .NET使用并行计算 提高执行效率
    关于线程安全中Lock的一些说明
    多线程中调用多参数的方法
    C#把汉字转换成拼音
    跨窗体Invoke时使用匿名方法或者带参方法
    给MP3音乐文件写ID3信息和专辑封面
    用Python作GIS:菜谱篇
    python中对象self的由来
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7795696.html
Copyright © 2011-2022 走看看