容易发现:大部分情况下f[x+1]=f[x]+1;
如果全部f[x],满足这个性质,则直接可以求出f[x]进行构造。
但由于x+k会发生进位,f[x]出现两个等差数列,中间出现断层。
且只会出现2个等差数列,因为k小于等于9,即x最多进位1次。(个位往前进位)
所以我们枚举个位c,如果k+c<=9,则不会发生进位。直接用等差数列求出f[x]即可。(f[x]+f[x]+1+k)*(k+1)/2 。
然后从个位进行构造,低位尽量取大数,这样高位可以取少一点,使得整体尽量小。
否则的话再枚举个位前面9的个数t,(因为个位发生进位,前面是9的话会发生连环进位)。
进位导致第二个等差数列的首项为第一个等差数列末项 +1 - 9*(t+1).
然后就可以求出f[x]了。
构造同上,不过注意满足后t+1位都是9.然后t+2位不能为9.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(){cnt=1,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
ll mi;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t--)
{
mi=2e18;
int n,k;
cin>>n>>k;
bool f=false;
for(int c=0;c<=9;c++)//枚举个位
{
if(c+k<=9)
{
int now=n-(1+k)*k/2;
if(now%(k+1)==0)
{
now/=(k+1);
ll tp=c,b=1;
now-=c;
if(now<0)continue;
while(now>9)
{
b*=10;
tp+=b*9;
now-=9;
}
if(now)b*=10,tp+=b*now;
// cout<<c<<" "<<tp<<" "<<mi<<endl;
mi=min(tp,mi);f=true;
}
continue;
}
for(int t=0;t<=15;t++)//十位之前连续9的个数
{
int now=n+(t+1)*9*(c+k-9)-(1+k)*k/2;
if(now%(k+1)==0)
{
now/=(k+1);
ll tp=c,b=1;now-=c;
for(int j=1;j<=t;j++)
{
b*=10;
tp+=b*9;
now-=9;
}
if(now<0)continue;
if(now>=8)b*=10,tp+=b*8,now-=8;
while(now>9)
{
b*=10;
tp+=b*9;
now-=9;
}
if(now)b*=10,tp+=b*now;
// cout<<c<<" "<<t<<" "<<tp<< endl;
mi=min(mi,tp);f=true;
}
//f[x]*(k+1)+(1+k)*k/2-(t+1)*9*(c+k-10)=n
}
}
if(f)cout<<mi<<endl;
else cout<<-1<<endl;
}
return 0;
}