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;
}
posted @ 2023-04-29 16:57  5k_sync_closer  阅读(9)  评论(0编辑  收藏  举报  来源