CF1567D 题解
CF1567D. Expression Evaluation Error
Description
给定一个十进制数 \(s\),现在将其分解为 \(n\) 个数,即这 \(n\) 个数做十进制加法的和为 \(s\)。求当这 \(n\) 个数在做 11 进制加法后得到的和最大的方案,如果有多种方案输出任意一种,共 \(t\) 组数据。
数据范围:\(1 \leq s \leq 10^9, 1 \leq n \leq \min(100, s), 1 \leq t \leq 100.\)
Solution
我们可以显然考虑到一个贪心策略:在分解数 \(s\) 的时候我们尽量避免借位,且尽量保留高位。这么做的原因是十进制加法满十进一,而十一进制则要满十一,较十进制进位困难。所以如果我们能少借位,且保留高位就可以得到一个最大的值。
不妨考虑按位贪心,将从高位向低位依次考虑先尽量将其拆成 \(10^k\) 的形式,但有可能会遇到 \(n\) 比较大拆出来的数不够的情况,我们只需在拆高位位时考虑还需要拆几次即可,这样就避免了拆出数不够的情况。
但是对于官方题解提到的使用单调队列的解法,细节比较多,尝试实现无果后通过翻 CF 上最短的提交记录翻到了以下做法。
Code
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
int n;
long long s;
inline void solve()
{
scanf("%lld%d", &s, &n);
long long cur;
for (int i = n - 1; i > 0; --i)
{
cur = pow(10, (int)log10(s - i));
s -= cur;
printf("%lld ", cur);
}
printf("%lld\n", s);
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
solve();
return 0;
}