zoukankan      html  css  js  c++  java
  • 【题解】P2602[JZOI2010]数字计数

    【题解】[P2602ZJOI2010]数字计数

    乍看此题,感觉直接从数字的位上面动手,感觉应该很容易。

    但是仔细看数据范围,发现如果不利用计数原理,肯定会超时,考虑数码出现的特征:

    (A000)(A999),四位数中的(A)总共出现了(999-0+1)次。假设(A)在第(k)位上,那么它出现了(10^{k-1})次。记录一下这个的前缀和。特别注意的是, 由(dp(i) ightarrow dp(i+1))时,要(dp(i+1)=10dp(i)+10^{i-1}),这是考虑到在第(i+1)位上增加一位会给(i)位带来([0,9])总共10的贡献。那么(A)出现的次数就被我们确定了。

    显然对于(A233)这样的数字,我们不能直接调用前面我们预处理的数组,因为它的值域是在([233,995])的,而非([000,999])。其实这样也好办,(A)出现的次数直接就是(233-000+1=233+1)。最后对于(A)特殊处理即可。

    然后我们从处理四位数到了处理三位数了。就是一个一样的子问题。

    #include<bits/stdc++.h>
    
    using namespace std;
    #define RP(t,a,b) for(register int t=(a),edd=(b);t<=edd;++t)
    #define DRP(t,a,b) for(register int t=(a),edd=(b);t>=edd;--t)
    #define ERP(t,a) for(register int t=head[a];t;t=e[t].nx)
    #define Max(a,b) ((a)<(b)?(b):(a))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define midd register int mid=(l+r)>>1
    #define TMP template < class ccf >
    typedef long long ll;
    #define endl '
    '
    #define spc ' '
    #define int ll
    TMP inline ccf qr(ccf b){
        char c=getchar();
        int q=1;
        ccf x=0;
        while(c<48||c>57)
    	q=c==45?-1:q,c=getchar();
        while(c>=48&&c<=57)
    	x=x*10+c-48,c=getchar();
        return q==-1?-x:x;
    }
    const int maxn=15;
    ll F,T;
    int cntf,cntt;
    int ans[maxn];
    int ans2[maxn];
    int num[maxn];
    ll dp[maxn]={0,1};
    ll ten[maxn]={1};
    
    inline void dfs(int* d,ll data){
        register int cnt=0;
        while(data)
    	num[++cnt]=data%10,data/=10;
        
        DRP(t,cnt,1){
    	RP(i,0,9)
    	    d[i]+=dp[t-1]*num[t];
    	RP(i,0,num[t]-1)
    	    d[i]+=ten[t-1];
    	register ll temp=0;
    	DRP(i,t-1,1)
    	    temp=temp*10LL+num[i];
    	d[num[t]]+=temp+1;d[0]-=ten[t-1];
        }
    }
    
    
    signed main(){
    #ifndef ONLINE_JUDGE
        freopen("in.in","r",stdin);
        freopen("out.out","w",stdout);
    #endif
        
        ten[1]=10;
        RP(t,2,14)
    	ten[t]=ten[t-1]*10ll,dp[t]=dp[t-1]*10ll+ten[t-1];
        
        F=qr(1ll);
        T=qr(1ll);
        
        dfs(ans,T);
        dfs(ans2,F-1LL);
    
        RP(t,0,9)
    	cout<<ans[t]-ans2[t]<<spc;
        cout<<endl;
        return 0;
    }
    
    
  • 相关阅读:
    【C】中malloc的使用
    【C++】const成员函数的作用
    C声明和定义
    【C++】指针与引用的区别
    【C】external/internal/static/register variable and function
    【C++】Sizeof与Strlen
    【面试题目】string类实现
    【C++】public,private,protected
    【Linux】僵尸进程
    【面试题目】翻转句子中单词的顺序
  • 原文地址:https://www.cnblogs.com/winlere/p/10356171.html
Copyright © 2011-2022 走看看