bzoj1833: [ZJOI2010]count 数字计数 && codevs1359 数字计数

bzoj1833

codevs1359

这道题也是道数位dp 因为0有前导0这一说卡了很久 最后发现用所有位数减1~9的位数就okay.....orzczl大爷 其他就跟51nod那道统计1出现次数一样啦

#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
LL read(){
    LL ans=0,f=1,c=getchar();
    while(c<‘0‘||c>‘9‘){if(c==‘-‘) f=-1; c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){ans=ans*10+(c-‘0‘); c=getchar();}
    return ans*f;
}
LL f[15][10][10],w[15],cur=15,ans1[15],ans2[15];
void prepare(){
    w[1]=1; for(int i=2;i<=12;i++) w[i]=w[i-1]*10;
    for(int i=0;i<=9;i++) f[1][i][i]=1;
    for(int i=2;i<=12;i++)
     for(int j=0;j<=9;j++)
      for(int k=0;k<=9;k++){
          for(int z=0;z<=9;z++)
              f[i][j][k]+=f[i-1][z][k];
          if(j==k) f[i][j][k]+=w[i];
      }
}
void work1(LL n){
    int cur=12;
    if(!n){ans1[0]=1; return ;}
    while(w[cur]>n) cur--;
    LL tot=1;
    for(int i=1;i<cur;i++) tot+=(w[i+1]-w[i])*i;
    tot+=(n-w[cur]+1)*cur;
    LL v=n/w[cur];
    for(int i=0;i<=9;i++)
     for(int j=0;j<v;j++)
      ans1[i]+=f[cur][j][i];
    ans1[v]=ans1[v]+n%w[cur]+1;
    n=n%w[cur];
    for(int i=cur-1;i;i--){
        v=n/w[i];
        for(int j=1;j<=9;j++)
            for(int k=0;k<v;k++) ans1[j]+=f[i][k][j];
        ans1[v]=ans1[v]+n%w[i]+1;
        n=n%w[i];
    }
    //printf("%lld %lld\n",tot,ans1[0]);
    for(int i=1;i<=9;i++) tot-=ans1[i]; ans1[0]=tot;
}
void work2(LL n){
    int cur=12;
    if(!n){ans2[0]=1; return ;}
    while(w[cur]>n) cur--;
    LL tot=1;
    for(int i=1;i<cur;i++) tot+=(w[i+1]-w[i])*i;
    tot+=(n-w[cur]+1)*cur;
    LL v=n/w[cur];
    for(int i=1;i<=9;i++)
     for(int j=0;j<v;j++)
      ans2[i]+=f[cur][j][i];
    ans2[v]=ans2[v]+n%w[cur]+1;
    n=n%w[cur];
    for(int i=cur-1;i;i--){
        v=n/w[i];
        for(int j=1;j<=9;j++)
            for(int k=0;k<v;k++) ans2[j]+=f[i][k][j];
        if(v) ans2[v]=ans2[v]+n%w[i]+1;
        n=n%w[i];
    }
    //printf("%lld %lld\n",tot,ans2[0]);
    for(int i=1;i<=9;i++) tot-=ans2[i]; ans2[0]=tot;
}
int main()
{
    prepare();
    work1(read()-1); work2(read());
    for(int i=0;i<=9;i++){
        printf("%lld",ans2[i]-ans1[i]);
        if(i!=9) printf(" ");
    }
    return 0;
}

时间: 2024-10-10 23:13:43

bzoj1833: [ZJOI2010]count 数字计数 && codevs1359 数字计数的相关文章

bzoj1833: [ZJOI2010]count 数字计数(数位DP+记忆化搜索)

1833: [ZJOI2010]count 数字计数 题目:传送门 题解: 今天是躲不开各种恶心DP了??? %爆靖大佬啊!!! 据说是数位DP裸题...emmm学吧学吧 感觉记忆化搜索特别强: 定义f[i][j][k]表示若前i个位置有k个j的此时的全局方案数,然后就可以记忆化搜索了(具体看代码吧) 代码: 1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath>

数位DP入门:bzoj1833: [ZJOI2010]count 数字计数

膜拜了一下蔡大神....然后突然想起来一些东西然后就填了一个半年多前的坑= = 人生第一道自己写的数位DP...好吧以前是看题解然后也不知道为什么就过了的>_< 数位DP介绍: http://wenku.baidu.com/link?url=9OS5Ybpw5wx00ahrH8ED2oyIlR1uWwrxT8N4pEg27GgBt2T2hLe4sd_h1rmpY7P0HmeHIEDw9h6_K98dPhhjoMhD2TpKcS8w1X8cC_dkPp_ 接下来是题目地址: http://www

BZOJ1833 [ZJOI2010]count 数字计数 【数学 Or 数位dp】

题目 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. 输入格式 输入文件中仅包含一行两个整数a.b,含义如上所述. 输出格式 输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次. 输入样例 1 99 输出样例 9 20 20 20 20 20 20 20 20 20 提示 30%的数据中,a<=b<=10^6: 100%的数据中,a<=b<=10^12. 题解 你以为我真的会写数位dp? 首先容斥一下,转化为求小于等于

bzoj1833 [ZJOI2010]count 数字计数

题目链接 我是DP弱者!!!我是DP弱者!!!我是DP弱者!!! 调了好久,数位DP好恼火QAQ 1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9

BZOJ1833: [ZJOI2010]count 数字计数 (数位dp)

传送门 数位dp... ...大概都是这个套路吧... ... 写这个的时候直接水了一发... ...我也不知道自己写的是不是dp... ... 大概是主要内容和dp关系不大的dp... ... mark代码..细长的代码真是丑啊..换行太频繁了.... 1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm&g

BZOJ1833 [ZJOI2010] count

[问题描述] 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. [输入格式] 输入文件中仅包含一行两个整数a.b,含义如上所述. [输出格式] 输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次. [输入样例] 1 99 [输出样例] 9 20 20 20 20 20 20 20 20 20 [数据范围] 30%的数据中,a<=b<=10^6: 100%的数据中,a<=b<=10^12. 正解:数位DP 解题报告: 只要

[bzoj1833][ZJOI2010][count] (数位dp)

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. So

1833: [ZJOI2010]count 数字计数

1833: [ZJOI2010]count 数字计数 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 2951  Solved: 1307[Submit][Status][Discuss] Description 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. Input 输入文件中仅包含一行两个整数a.b,含义如上所述. Output 输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次.

【BZOJ-1833】count数字计数 数位DP

1833: [ZJOI2010]count 数字计数 Time Limit: 3 Sec  Memory Limit: 64 MBSubmit: 2494  Solved: 1101[Submit][Status][Discuss] Description 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. Input 输入文件中仅包含一行两个整数a.b,含义如上所述. Output 输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次.