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

    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。

    Source

    Day1


    这种裸的数位Dp只有我这蒟蒻不会做吧...

    设f[i][j][k]为长度为i, 开头为j, k这个数字出现的次数。

    然后就不会了。


    #include <iostream>
    #include <cstdio>
    using namespace std;
    
    typedef long long ll;
    struct date
    {
        ll num[10];
        friend date operator + (date a, date b)
        {
            date t;
            for (int i = 0 ; i <= 9 ; i ++) t.num[i] = b.num[i] + a.num[i];
            return t;
        }
    }f[25][10];
    ll a, b, t[25];
    date cal(ll x)
    {
        date ans;
        for (int i = 0 ; i <= 9 ; i ++) ans.num[i] = 0;
        if(!x){ans.num[0]=1;return ans;}
        int len = 15;
        while(t[len] > x) len--;
        for (int i = 1 ; i < len ; i ++)
            for (int j = 1 ; j <= 9 ; j ++)
                ans = ans + f[i][j];
        ans.num[0]++;
        int lim = x / t[len];
        for (int i = 1 ; i < lim ; i ++) ans = ans + f[len][i];
        x %= t[len];
        ans.num[lim] += x + 1;
        for (int i = len - 1 ; i ; i --)
        {
            lim = x / t[i];
            for (int j = 0 ; j < lim ; j ++) ans = ans + f[i][j];
            x %= t[i];
            ans.num[lim] += x + 1;
        }
        return ans;
    }
    
    
    int main()
    {
        t[1] = 1;for (int i = 2 ; i <= 15 ; i ++) t[i] = t[i-1] * 10;
        for (int i = 0 ; i <= 9 ; i ++) f[1][i].num[i] = 1;
        for (int i = 2 ; i <= 12 ; i ++)
        {
            for (int x = 0 ; x <= 9 ; x ++)
            {
                for (int y = 0 ; y <= 9 ; y ++)
                {
                    f[i][y] = f[i][y] + f[i-1][x];
                    f[i][y].num[y] += t[i-1];
                }
            }
        }
        scanf("%lld%lld", &a, &b);
        date t1 = cal(a-1), t2 = cal(b);
        for (int i = 0 ; i <= 8 ; i ++) printf("%lld ",t2.num[i] - t1.num[i]);
        printf("%lld", t2.num[9] - t1.num[9]);
        return 0;
    }
  • 相关阅读:
    php命令注入
    mysql事物
    安装php环境
    移除服务器缓存实例
    show user profile synchronization tools
    manual start user profile import
    JSON is undefined. Infopath Form People Picker in SharePoint 2013
    asp.net web 应用站点支持域账户登录
    Load sharepoint envirement by powershell
    sharepoint 2016 download
  • 原文地址:https://www.cnblogs.com/BriMon/p/9370700.html
Copyright © 2011-2022 走看看