• Educational Codeforces Round 50 (Rated for Div. 2) C. Classy Numbers


    C. Classy Numbers

    题目链接:https://codeforces.com/contest/1036/problem/C

    题意:

    给出n个询问,每个询问给出Li,Ri,问在这个闭区间中有多少个数满足,除开0之外,最多只有4个数字。

    题解:

    由于题目给出的数满足前缀性质,所以我们可以直接求[1,r]这个区间中有多少个数满足就好了。

    具体做法就是从高位往低位来看,然后如果当前数组不为0,假设为p,那么当前数组对答案的贡献就比较好计算了,假设后面的数有x位,目前已经有k个数字了。

    那么分两种情况:一种是当前这位为0的时候,那么贡献就是C(x,3-k);另外一种就是当前这位为1~p-1的时候,贡献就是(p-1)*C(x,3-k-1)。

    当前为p的情况我们留在后面统计就行了,因为这种情况主要是取决后面的数的。

    细节见代码吧:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll C[30][30];
    int T;
    ll a,b;
    int num[30],pow9[30]={1,9,81,729};
    ll calc(ll x,ll k){
        ll ans = 0;
        if(x<=0) return 1;
        for(int i=0;i<=k;i++) ans+=C[x][i]*pow9[i];
        return ans ;
    }
    ll solve(ll x){
        memset(num,0,sizeof(num));
        int n;
        for(n=1;x;n++){
            num[n]=x%10;
            x/=10;
        }
        n--;
        ll ans = 0;
        for(int i=n,cur=3;i>=1;i--){
            if(!num[i]) continue ;
            ans+=calc(i-1,cur);
            cur--;
            ans+=(num[i]-1)*calc(i-1,cur);
            if(cur==0) break ;
            //if(i==1) ans++;
        }
        return ans ;
    }
    int main(){
        ios::sync_with_stdio(false);cin.tie(0);
        C[1][0]=1;C[1][1]=1;
        for(int i=2;i<=20;i++){
            C[i][0]=1;
            for(int j=1;j<=i;j++){
                C[i][j]=C[i-1][j]+C[i-1][j-1];
            }
        }
        cin>>T;
        while(T--){
            cin>>a>>b;
            //cout<<solve(b)<<" "<<solve(a-1)<< '
    ';
            cout<<solve(b)-solve(a-1)<< '
    ';
        }
        return 0;
    }
  • 相关阅读:
    校验规则,纯数字。几位有效数字,保留几位小数
    银行卡校验规则(Luhn算法)
    forEach兼容ie8
    node.js
    gulp
    observer
    webpack.config.js 配置
    内存泄漏(Memory Leak)
    cdn
    前端 各种插件的官网
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10549300.html
Copyright © 2020-2023  润新知