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 }
  • 相关阅读:
    Balance的数学思想构造辅助函数
    1663. Smallest String With A Given Numeric Value (M)
    1680. Concatenation of Consecutive Binary Numbers (M)
    1631. Path With Minimum Effort (M)
    1437. Check If All 1's Are at Least Length K Places Away (E)
    1329. Sort the Matrix Diagonally (M)
    1657. Determine if Two Strings Are Close (M)
    1673. Find the Most Competitive Subsequence (M)
    1641. Count Sorted Vowel Strings (M)
    1679. Max Number of K-Sum Pairs (M)
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7795696.html
Copyright © 2011-2022 走看看