对 \(n \le 150, k \le 9\),求最小的非负整数 \(x\) 满足 \(f(x)+f(x+1)+...+f(x+k)=n\),其中 \(f(x)\) 表示 \(x\) 的各个数位的和。
每增加一位数,数字大小的增长是指数的,而 \(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();
}
原文:https://www.cnblogs.com/mollnn/p/13938838.html