[CF1373E] Sum of Digits

Description

(n le 150, k le 9),求最小的非负整数 (x) 满足 (f(x)+f(x+1)+...+f(x+k)=n),其中 (f(x)) 表示 (x) 的各个数位的和。

Solution

每增加一位数,数字大小的增长是指数的,而 (f) 值的增长是线性的。

比如 (k=1) 时,(f(8)+f(9)=17),而 (f(80)+f(81)=17)(f(98)+f(99)=35),而 (f(980+981)=35)

猜想我们可以将所有合法的 (n) 表示成 (f(x)+...+f(x+k)) 的形式,且一定有 (a99..99bc) 这样形式的 (x) 满足条件,本质上我们相当于暴力枚举了 (x) 的长度,最高位,最低二位的值,将它表示为 (i imes 10^j - l),枚举 (i,j,l)(边界不大会证明)

#include <bits/stdc++.h>
using namespace std;

#define int long long 
const int N = 1005;

int n,k,t;

int f(int x)
{
    int ans=0;
    while(x) ans+=x%10, x/=10;
    return ans;
}

void solve()
{
    cin>>n>>k;
    for(int nPow=10;nPow<2e16;nPow*=10)
    {
        for(int nFir=1;nFir<=9;nFir++)
        {
            for(int nDelta=0;nDelta<=30;nDelta++)
            {
                int x=nPow*nFir-30+nDelta;
                if(x>=0)
                {
                    int tmp=0;
                    for(int i=x;i<=x+k;i++) tmp+=f(i);
                    if(tmp==n) 
                    {
                        cout<<x<<endl;
                        return;
                    }
                }
            }
        }
    }
    cout<<-1<<endl;
}

signed main()
{
    ios::sync_with_stdio(false);

    cin>>t;
    while(t--) solve();
}
原文地址:https://www.cnblogs.com/mollnn/p/13938838.html