首页 > 其他 > 详细

[CF1373E] Sum of Digits - 构造

时间:2020-11-06 22:39:53      阅读:32      评论:0      收藏:0      [点我收藏+]

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 \times 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();
}

[CF1373E] Sum of Digits - 构造

原文:https://www.cnblogs.com/mollnn/p/13938838.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!