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;
}
posted @ 2021-09-18 10:59  Nickel_Angel  阅读(40)  评论(0编辑  收藏  举报