Sum of Digits
Problem Description
Let f ( x ) f(x) f(x) be the sum of digits of a decimal number x.
Find the smallest non-negative integer x x x such that f ( x ) + f ( x + 1 ) + ⋯ + f ( x + k ) = n f(x)+f(x+1)+⋯+f(x+k)=n f(x)+f(x+1)+⋯+f(x+k)=n.
Input
The first line contains one integer t t t ( 1 ≤ t ≤ 150 1≤t≤150 1≤t≤150) — the number of test cases.
Each test case consists of one line containing two integers n n n and k k k ( 1 ≤ n ≤ 150 1≤n≤150 1≤n≤150, 0 ≤ k ≤ 9 0≤k≤9 0≤k≤9).
Output
For each test case, print one integer without leading zeroes. If there is no such x x x that f ( x ) + f ( x + 1 ) + ⋯ + f ( x + k ) = n f(x)+f(x+1)+⋯+f(x+k)=n f(x)+f(x+1)+⋯+f(x+k)=n, print − 1 −1 −1; otherwise, print the minimum x x x meeting that constraint.
Sample Input
7
1 0
1 1
42 7
13 7
99 1
99 0
99 2
Sample Output
1
0
4
-1
599998
99999999999
7997
题意
设 f ( x ) f(x) f(x)等于x各位数字和。给定n和k,求最小的x满足 f ( x ) + f ( x + 1 ) + ⋯ + f ( x + k ) = n f(x)+f(x+1)+⋯+f(x+k)=n f(x)+f(x+1)+⋯+f(x+k)=n。
题解
x,x+1, … , x+k,是连续的,所以满足条件的x,连续的数中要么只有最后一位不同,要么会存在进位。
x必定为abc形式,其中a代表数位和为
n
−
9
∗
b
−
c
n-9*b-c
n−9∗b−c的最小的数,b为若干个9(可以为0个),c为个位。
枚举c,求出
x
x
x到
x
+
k
x+k
x+k个位数上的和记为m。
若
c
+
k
<
10
c+k<10
c+k<10,则不会存在进位,则c固定后,贪心使a最小即可(从低位到高位尽可能放9)。
若
c
+
k
≥
10
c+k\ge10
c+k≥10,则枚举b部分,设9的个数为
j
j
j,则进位前,共有
10
−
c
10-c
10−c个数,其对于结果的贡献为
9
∗
j
∗
(
10
−
c
)
9*j*(10-c)
9∗j∗(10−c);进位后,共有
(
c
+
k
)
%
10
+
1
(c+k)\%10+1
(c+k)%10+1个数,b部分由于进位都变为0,则a部分相比之前,数位和多1。此时x的b,c部分已知,求a部分即可。
注意:
确定b,c部分数位和mm后,(n-mm)可能不能整除(k+1)。
最终结果x在LL范围内,但枚举时,则有部分结果会爆LL,可以考虑用字符串处理x。
#include<stdio.h>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<iterator>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define LLINF 0x3f3f3f3f3f3f3f3f
#define eps 1e-6
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 200100;
const int mod = 998244353;
LL solve(int n, int k);
int main()
{
int n, m, i, k, t;
scanf("%d", &t);
while(t--)
{
scanf("%d %d", &n, &k);
printf("%I64d\n", solve(n, k));
}
return 0;
}
LL solve(int n, int k)
{
int i, j, a, m, mm, ss;
LL ans = LLINF, x, tmp;
for(i=0;i<10;i++){
m = i%10;
for(j=1;j<=k;j++)
m += (i+j)%10;
if(i+k < 10){
if(n < m || (n-m)%(k+1) != 0)continue;
ss = (n-m)/(k+1);
x = i, tmp = 10;
while(ss){
x += min(ss, 9)*tmp;
tmp *= 10, ss -= min(ss, 9);
}
ans = min(ans, x);
continue;
}
for(j=0;j<13;j++){
if(i+k >= 10) mm = m+9*j*(10-i)+(i+k)%10+1;
else mm = m+9*j*(k+1);
if(mm <= n && (n-mm)%(k+1) == 0){
x = i, tmp = 10;
for(a=1;a<=j;a++){
x += 9*tmp;
tmp *= 10;
}
int ss = (n-m)/(k+1);
x += min(ss, 8)*tmp;
tmp *= 10, ss -= min(ss, 8);
//因为中间结果可能爆LL,所以不科学的用tmp<1e18处理爆LL的情况
while(ss && tmp < 1e18){
x += min(ss, 9)*tmp;
tmp *= 10, ss -= min(ss, 9);
}
if(!ss)ans = min(ans, x);
}
}
}
if(ans == LLINF)return -1;
else return ans;
}