P9215 [入门赛 #11] [yLOI2021] 扶苏与 1 (Hard Version) 题解
按 $0$ 的连续段“分块”,记第 $i$ 个 $0$ 的连续段的左端点为 $l_i$($l_0=1$),则第 $i$ 块为 $[l_{i-1},l_i)$,
即每一块为 $0\cdots 0+s$ 的形式,其中 $s$ 为任意不含 $0$ 的串。
容易发现块内塞满 $9$ 可以产生块长次进位,所以把前若干个整块塞满 $9$。
然后发现块内长度为 $x$ 的后缀塞满 $9$ 可以产生 $x$ 次进位,所以把剩下一个散块的后缀塞满 $9$。
所有块长之和 $<k$ 无解。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int T, n, k, f, t, z;char s[10050];
int main()
{
scanf("%d", &T);while(T--)
{
scanf("%s%d", s + 1, &k);f = n = strlen(s + 1);
while(s[f] == '0') --f;if(f < k) {puts("-1");continue;}t = 1;
while(k)
{
z = 1;while(s[t] == '0') ++t, ++z;
for(int i = 0;i < z - k;++i) putchar('0');
for(int i = 0;i < min(z, k);++i) putchar('9');
k -= min(z, k);++t;
}
for(int i = t;i <= n;++i) putchar('0');puts("");
}
return 0;
}