[ZJOI2010]count 数字计数

本人水平有限,题解不到为处,请多多谅解

本蒟蒻谢谢大家观看

 

传送门:题目

Problem B: [ZJOI2010]count 数字计数

Time Limit: 3 Sec  Memory Limit: 64 MB
Submit: 113  Solved: 69
[Submit][Status][Web Board]

Description

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

Input

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

Output

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

Sample Input

1 99

Sample Output

9 20 20 20 20 20 20 20 20 20

HINT

//F[i][j][t]是i位数,最开始一位是j有多少个t
//F[i][k][t]是i位数,最开始一位是k有多少个t

此题运用前缀和思想 sum(b+1)-sum(a)

#include<bits/stdc++.h>
#define ll long long
//F[i][j][t]是i位数,最开始一位是j有多少个t
//F[i][k][t]是i位数,最开始一位是k有多少个t
using namespace std;
ll n,m,f[13][10][10],ans[10],h[13];
int s1[13],s2[13];
char a[13],b[13];
int main()
{
//    freopen("qq.out","w",stdout);
    scanf("%s%s",a+1,b+1);
    h[0]=1;
    for(int i=1;i<=15;i++)h[i]=h[i-1]*10;
    int l1=strlen(a+1),l2=strlen(b+1);
    for(int i=1;i<=l1;i++){
        s1[i]=a[l1-i+1]-'0';
        n=n*10+a[i]-'0';
    //    cout<<"s1[i]= "<<s1[i]<<endl;
    }
    for(int i=1;i<=l2;i++){
        s2[i]=b[l2-i+1]-'0';
        m=m*10+b[i]-'0';
    //    cout<<"s2[i]= "<<s2[i]<<endl;
    }
    for(int i=1;i<=l2;i++){
        for(int j=0;j<=9;j++){
            for(int t1=0;t1<=9;t1++){
                for(int k=0;k<=9;k++){
                    f[i][j][t1]+=f[i-1][k][t1];
                }
                if(t1==j){

    //if(j==t)f[i][j][t]+=10^(i-1);       考虑前导0的存在   0000000j  ~    

 
  

                                000000j   ~  ……


                    f[i][j][t1]+=h[i-1];
                }
                //if(j==t)f[i][j][t]+=10^(i-1);
            }
        }
    }
    for(int i=l2;i;i--){
        ans[s2[i]]+=m%h[i-1]+1;
        ans[0]-=h[i-1];
        for(int j=0;j<s2[i];j++)
            for(int k=0;k<=9;k++)
                ans[k]+=f[i][j][k];
    }
    for(int i=l1;i;i--){
        ans[s1[i]]-=n%h[i-1];
        ans[0]+=h[i-1];
        for(int j=0;j<s1[i];j++)
            for(int k=0;k<=9;k++)
                ans[k]-=f[i][j][k];
    }
    for(int i=0;i<9;i++)
        cout<<ans[i]<<" "; 
    cout<<ans[9]<<endl;
    return 0;
}

转载于:https://www.cnblogs.com/nlyzl/p/11263741.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值