1 条题解

  • 0
    @ 2025-8-24 22:54:11

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar mango2011
    Vegetable Vegetable Little Cat

    搬运于2025-08-24 22:54:11,当前版本为作者最后更新于2024-01-11 18:27:58,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    这道题算是比较套路的一道题目吧,下面是我的方法:

    1.1. 由于 kk 的值巨大,所以不可能真的模拟,容易验证当 k4k\ge4 时,最终的值一定是一位数(变成一位数之后不再改变),所以,如果 k4k\ge4,则令 k=4k=4

    2.2. 由于 f(n)f(n) 的值下降迅速,而 nn 的值很大,所以考虑先进行一次操作,于是易知新的 n9000n'\le9000,可以进行计算。

    3.3. 经过上面两步的转化,对于任意一个满足 g(t,min(4,k)1)=mg(t,\min(4,k)-1)=mtt,答案都可以加上 n\le n 并且数位和为 tt 的数的个数。

    4.4. 由于 33,即把统计答案的过程分为两部分:

    1)1) 统计数位和为 t(t9000)t(t\le9000) 的数的个数(非常简单的数位 dpdp)。

    2)2) 按照 33 的思路统计答案。

    5.5. 时间复杂度正确,可以通过。

    6.6. 代码实现(码丑勿喷):

    #include<bits/stdc++.h>
    using namespace std;
    string s;
    int m,k,l,dp[1005][9005];
    const int mod=1e9+7;
    int o(int x)
    {
        int res=0;
        while(x)
        {
            res+=x%10;
            x/=10;
        }
        return res;
    }
    bool pd(int x)
    {
        int i;
        for(i=1;i<=k;i++)
        {
            x=o(x);
        }
        if(x==m)
        {
            return true;
        }
        return false;
    }
    void solve()
    {
        int i,j,k,sum=s[0]-'0';
        memset(dp,0,sizeof(dp));
        for(i=0;i<s[0]-'0';i++)
        {
            dp[0][i]=1;
        }
        for(i=1;i<l;i++)
        {
            for(j=0;j<=9*(i+1);j++)
            {
                if(j-sum<s[i]-'0'&&j-sum>=0)
                {
                    dp[i][j]++;
                }
                for(k=0;k<=9;k++)
                {
                    if(k>j)
                    {
                        break;
                    }
                    dp[i][j]+=dp[i-1][j-k];
                    dp[i][j]%=mod;
                }
            }
            sum+=s[i]-'0';
        }
        dp[l-1][sum]++;
    }
    int main()
    {
        ios::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL);
        int T,ans,i;
        cin>>T;
        while(T--)
        {
            cin>>s>>k>>m;
            if(k>4)
            {
                k=4;
            }
            k--;
            l=s.size();
            solve();
            ans=0;
            for(i=1;i<=9000;i++)
            {
                if(pd(i))
                {
                    ans+=dp[l-1][i];
                    ans%=mod;
                }
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    
    • 1

    信息

    ID
    9666
    时间
    1000ms
    内存
    512MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者