• [ZJOI2010]数字计数/烦人的数学作业


    洛咕

    洛咕

    题意:给定两个正整数(l)(r),求在([l,r])中的所有整数中,每个数码各出现了多少次.((1<=l<=r<<10^{12}))

    题意:给出一个区间([l,r]),求([l,r])内每个数的数字和 的和(对(1e9+7)取模).如(123)这个数的数字和为(1+2+3=6.1<=l<=r<=10^{18}.)

    这两道题只是输出的东西不一样,过程是完全一样的.

    分析:对0~9这十个数字分别进行数位DP即可.具体怎么求,套模板就行了.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline ll read(){
        ll x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    int len,a[20];ll dp[20][20][20];
    inline ll dfs(int pos,int pre,int sum,int lead,int limit,int goal){
    //pos当前考虑到哪一位
    //pre上一位填的是什么
    //sum当前共出现了几次goal这个数
    //lead判断是否有前导零
    //limit判断是否有填数限制
    //goal当前DP要统计的是哪个数出现的次数
        if(pos>len)return sum;//找到了一个合法的数,返回答案
    	if(dp[pos][pre][sum]!=-1&&!limit&&!lead)return dp[pos][pre][sum];//记忆化搜索
        ll cnt=0;int res=limit?a[len-pos+1]:9;
        for(int i=0;i<=res;++i){
            if((!i)&&lead)cnt+=dfs(pos+1,0,0,1,limit&&(i==res),goal);
            else if(i&&lead)cnt+=dfs(pos+1,i,(i==goal),0,limit&&(i==res),goal);
            else cnt+=dfs(pos+1,i,sum+(i==goal),0,limit&&(i==res),goal);
        }
    	return (!limit&&!lead)?dp[pos][pre][sum]=cnt:cnt;
    }
    inline ll part(ll x,int num){
    	len=0;while(x)a[++len]=x%10,x/=10;
    	memset(dp,-1,sizeof(dp));
    	return dfs(1,0,0,1,1,num);
    }
    int main(){
    	ll l=read(),r=read();
    	for(int i=0;i<=9;++i)
    		printf("%lld ",part(r,i)-part(l-1,i));
    	printf("
    ");
        return 0;
    }
    
    

    就 把每个数字出现的次数乘上这个数字 然后加起来就是答案了.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline ll read(){
        ll x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int mod=1e9+7;
    int len,a[20];ll dp[20][20][20];
    inline ll dfs(int pos,int pre,int sum,int lead,int limit,int goal){
    	if(pos>len)return sum%mod;
    	if(dp[pos][pre][sum]!=-1&&!limit&&!lead)return dp[pos][pre][sum];
        ll cnt=0;int res=limit?a[len-pos+1]:9;
        for(int i=0;i<=res;++i){
            if((!i)&&lead)cnt+=dfs(pos+1,0,0,1,limit&&(i==res),goal);
            else if(i&&lead)cnt+=dfs(pos+1,i,(i==goal),0,limit&&(i==res),goal);
            else cnt+=dfs(pos+1,i,sum+(i==goal),0,limit&&(i==res),goal);
        }
    	return (!limit&&!lead)?dp[pos][pre][sum]=cnt:cnt;
    }
    inline ll part(ll x,int num){
    	len=0;while(x)a[++len]=x%10,x/=10;
    	memset(dp,-1,sizeof(dp));
    	return dfs(1,0,0,1,1,num)%mod;
    }
    int main(){
    	int T=read();
    	while(T--){
    		ll l=read(),r=read(),ans=0;
    		for(int i=1;i<=9;++i)ans=((ans+i*(part(r,i)-part(l-1,i)))%mod+mod)%mod;//0没必要考虑
    		printf("%lld
    ",ans);
    	}
        return 0;
    }
    
    
  • 相关阅读:
    svn command line tag
    MDbg.exe(.NET Framework 命令行调试程序)
    Microsoft Web Deployment Tool
    sql server CI
    VS 2010 One Click Deployment Issue “Application Validation did not succeed. Unable to continue”
    mshtml
    大厂程序员站错队被架空,只拿着五折工资!苟活和离职,如何选择?
    揭秘!Windows 为什么会蓝屏?微软程序员竟说是这个原因...
    喂!千万别忘了这个C语言知识!(~0 == -1 问题)
    Linux 比 Windows 更好,谁反对?我有13个赞成理由
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11585678.html
Copyright © 2020-2023  润新知