题解:CF1373E Sum of Digits
William2022 · · 题解
约定
本文约定
例如
显然有
方法
因为
再观察样例,就不难想出将答案表示成这样。
其中,
因为
做法
我们把
有的时候可能不会进位,也就没有第二块。
第一块大小表示
因为总共有
要注意的事是:
1.总共有
2.块长非负。
记两块长度为:
那么
对上面所有数进行
可以得到:
答案计算
在已知
如果
否则填入
其中
得出这次对应得答案为
所有答案取
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF=9e18;
void add(ll &a,ll b){// 拼接函数,将 a 拼上 b
for(ll b1=b;b1;b1/=10)a*=10;
a+=b;
}
ll construct(int fp,int t,int r){// 输入 f(p),t,r 返回最小的 x
ll fr=0;
if(fp<=8)add(fr,fp);
else{
fp-=8;// 末尾会填入 8
if(fp%9)add(fr,fp%9);
for(;fp>=9;fp-=9)add(fr,9);// 尽可能用 9
add(fr,8);// 末尾一个 8,因为 p 的末尾不能是 9
}
while(t--)add(fr,9);
if(r)add(fr,r); else fr*=10;//我的拼接函数拼不上 0
return fr;
}
ll solve(){
ll n,k;
cin>>n>>k;
ll ans=INF;
ll A,B;
for(int t=0;t<=18;t++){
for(int r=0;r<=9;r++){
A=10-r; B=(k+1)-(10-r);
A=min(A,k+1); B=max(B,0LL); //块长限制
ll D=n-B-9*A*t-A*r-(A*(A-1)+B*(B-1))/2;
if(D<0 || D%(k+1))continue;
ll fp=D/(k+1);
ans=min(ans,construct(fp,t,r));
}
}
if(ans>=INF)return -1;
return ans;
}
signed main(){
ios::sync_with_stdio(0); cin.tie(0);
int T; cin>>T;
while(T--)cout<<solve()<<'\n';
}