1 条题解

  • 0
    @ 2026-10-31 17:57:32

    思路

    题意简述:每次操作可以给 nn 加上一个十进制表示全由数字 9 组成的正整数(9,99,999,…9,99,999,\dots),可以操作任意多次。求最少的操作次数,使得结果中至少有一位是 7。

    先看一次操作的效果。任意一个全 9 的数都可以写成

    10p−1(p≥1),10^p-1\qquad(p\ge 1),

    也就是说,它在个位上减 1,同时在从右往左第 pp 位上“加 1”。做 ll 次操作后:

    $$n+\sum_{i=1}^{l}(10^{p_i}-1)=n-l+\sum_{i=1}^{l}10^{p_i}.$$

    因此可以把过程理解为:

    1. 先在个位上统一减掉 ll,得到基础数 m=n−lm=n-l;
    2. 再把 ll 个“加一”分配给较高的数位(每个操作贡献一个 10pi10^{p_i})。

    要让结果中出现 7,最省“加一”的办法是:在 mm 中找一个不超过 7 的数位 dd,把 7−d7-d 个增量加在这一位上,使它恰好变成 7;剩余的增量可以加到更高位的新列上,不会破坏已经得到的 7。数字 8、9 只会继续增大(产生进位),不能直接变成 7,所以不参与选择。

    于是设 mdmd 为 m=n−lm=n-l 中不超过 7 的最大数位,ll 次操作可行的条件就是

    l≥7−md.l\ge 7-md.

    从小到大枚举 ll,第一个满足条件的 ll 就是最少操作次数。

    关于枚举范围:l=7l=7 时一定有 7−md≤77-md\le 7(md≥0md\ge0),且 n≥10n\ge10 保证 n−7>0n-7>0,所以答案一定不超过 7,循环到 9 足够。l=0l=0 则覆盖了 nn 本身已含 7 的情况(此时 md=7md=7,条件 0≥00\ge0 成立)。

    复杂度:每组数据只枚举 10 次,每次处理 O(log⁡n)O(\log n) 个数位,总时间 O(tlog⁡n)O(t\log n),空间 O(log⁡n)O(\log n)(字符串开销)。

    代码

    #include<bits/stdc++.h>
    #define int long long
    #define dd double
    #define str string
    #define el cout << endl
    #define re return
    #define ff first
    #define ss second
    #define pll pair<int,int>
    #define pdd pair<dd,dd>
    #define all(x) x.begin(),x.end()
    #define pb push_back
    #define sz(x) (int) x.size()
    using namespace std;
    
    void go(){
        int n;
        cin >> n;
    
        // 从小到大枚举操作次数 l,第一个可行的 l 即为答案
        for (int l = 0; l <= 9; l++) {
            // l 次操作先贡献个位上的 -l,得到基础数 n-l
            string s = to_string(n - l);
    
            // md 记录 n-l 中不超过 7 的最大数位(8、9 无法直接变成 7,忽略)
            int md = 0;
            for (auto c: s) {
                if (c <= '7') {
                    md = max(md, (int)(c - '0'));
                }
            }
    
            // 把该数位补到 7 需要 7-md 次“加一”,l 足够即可行
            if (l >= 7 - md) {
                cout << l << '\n';
                return;
            }
        }
    }
    
    signed main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);cout.tie(nullptr);
        int t=1;
        cin >>t;
        // 多组测试数据
        while(t--){
            go();
        }
        return 0;
    }
    
    • 1

    信息

    ID
    50
    时间
    1000ms
    内存
    256MiB
    难度
    3
    标签
    递交数
    0
    已通过
    0
    上传者