zoukankan      html  css  js  c++  java
  • 数字计数

    题目链接:https://loj.ac/problem/10169

    题意:给定两个正整数 l 和 r,求在[l,r]中的所有整数中,每个数字各出现了多少次。

    思路:数位dp,维护每个数字出现次数和数字个数即可,在计数时,比如十位是1,那1的贡献还要加上个位所以可能的数。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    struct node
    {
        ll s;
        ll b[10];
        node()
        {
            s=0;
            for(int i=0;i<10;i++)
                b[i]=0;
        }
    }dp[30];
    int a[30];
    //pos : 位数  qd : 是否为前导  flag : 是否处于上边界 
    node dfs(int pos,bool qd,bool flag)
    {
        if(pos==0)
        {
            node t;
            t.s=1;
            return t;
        }
        int up=flag?a[pos]:9;//确定上边界
        if((!flag)&&(!qd)&&dp[pos].s)//如果之前已经求出,则直接返回
            return dp[pos];
        node tmp;
        tmp.s=0;
        for(int i=0;i<10;i++)
            tmp.b[i]=0;
        for(int i=0;i<=up;i++)
        {
            node t=dfs(pos-1,qd&&i==0,flag&&i==up);
            tmp.s+=t.s;
            for(int j=0;j<10;j++)
                tmp.b[j]+=t.b[j];
            if(!qd || i!=0)//如果此时已经不是前导0,那i出现的次数要加上t.s 
                tmp.b[i]+=t.s;
        }
        if((!flag)&&(!qd))
            dp[pos]=tmp;//记录值,方便下次直接返回
        return tmp;
    }
    node fun(ll x)
    {
        int pos=0;
        while(x)//将x的每一位进行分解
        {
            a[++pos]=x%10;
            x/=10;
        }
        return dfs(pos,true,true);
    }
    int main()
    {
        ll l,r;
        cin>>l>>r;
        node x=fun(r);
        node y=fun(l-1);
        for(int i=0;i<10;i++)
            cout<<x.b[i]-y.b[i]<<" ";
        cout<<endl;
    }
  • 相关阅读:
    202103226-1 编程作业
    MSF原则
    介绍
    4 20210412-1 原型设计作业
    案例分析作业
    第二次编程
    阅读任务
    自我介绍
    案例分析作业
    阅读任务
  • 原文地址:https://www.cnblogs.com/zcb123456789/p/13750602.html
Copyright © 2011-2022 走看看