zoukankan      html  css  js  c++  java
  • 【BZOJ-1833】count数字计数 数位DP

    1833: [ZJOI2010]count 数字计数

    Time Limit: 3 Sec  Memory Limit: 64 MB
    Submit: 2494  Solved: 1101
    [Submit][Status][Discuss]

    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

    Solution

    裸的数位DP,但其实并不是特别的水

    首先F[i][j][k]表示位数为i的最高位为j的k种数的个数

    按照十进制拆分,预处理后统计答案

    Code

    #include<iostream> 
    #include<cstdio> 
    #include<algorithm> 
    #include<cstring> 
    #include<cmath> 
    using namespace std; 
    long long L,R; 
    long long F[15][10][10],ans1[10],ans2[10]; 
    void prework() 
    { 
        for (int i=0; i<=9; i++) F[1][i][i]=1; 
        long long tmp=1; 
        for (int i=2; i<=12; i++) 
            { 
                tmp*=10; 
                F[i][0][0]=F[i-1][1][0]*9+F[i-1][0][0]+tmp; 
                for (int j=1; j<=9; j++)  
                    F[i][0][j]=F[i-1][0][j]*9+F[i-1][j][j]; 
                for (int j=1; j<=9; j++) 
                    { 
                        F[i][j][0]=F[i-1][1][0]*9+F[i-1][0][0]; 
                        for (int k=1; k<=9; k++) 
                            if (j==k) 
                                F[i][j][k]=F[i-1][0][k]*9+F[i-1][k][k]+tmp; 
                            else 
                                F[i][j][k]=F[i-1][0][k]*9+F[i-1][k][k]; 
                    } 
            } 
    } 
    long long cf(int x) 
    { 
        long long re=1; 
        for (int i=1; i<x; i++) 
            re*=10; 
        return re; 
    } 
    void Calc(long long x,long long *ans) 
    { 
        int digit[15]={0},len=0; long long y=x; 
        while (x) {digit[++len]=x%10; x/=10;} 
        for (int i=1; i<len; i++) 
            for (int j=1; j<=9; j++) 
                for (int k=0; k<=9; k++) 
                    ans[k]+=F[i][j][k]; 
        for (int i=len; i>=1; i--) 
            { 
                for (int j=0; j<=digit[i]-1; j++) 
                    { 
                        if (i==len && j==0) continue; 
                        for (int k=0; k<=9; k++) ans[k]+=F[i][j][k]; 
                    } 
                ans[digit[i]]+=y%cf(i)+1;            
            } 
    } 
    int main() 
    { 
        prework(); 
        scanf("%lld%lld",&L,&R); 
        Calc(L-1,ans1); Calc(R,ans2); 
        printf("%lld",ans2[0]-ans1[0]); 
        for (int i=1; i<=9; i++) printf(" %lld",ans2[i]-ans1[i]); 
        return 0; 
    }

    自己一开始YY的出错了..

  • 相关阅读:
    phpcms后台进入地址(包含No permission resources错误)
    phpmyadmin上传大sql文件办法
    ubuntu彻底卸载mysql
    Hdoj 2602.Bone Collector 题解
    一篇看懂词向量
    Hdoj 1905.Pseudoprime numbers 题解
    The Python Challenge 谜题全解(持续更新)
    Hdoj 2289.Cup 题解
    Hdoj 2899.Strange fuction 题解
    Hdoj 2199.Can you solve this equation? 题解
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5447617.html
Copyright © 2011-2022 走看看