1 条题解

  • 0
    @ 2026-6-19 10:31:09

    📝 题目大意

    给定正整数 NN,在所有满足 f(x)=Nf(x) = Nf(x)f(x) 表示 xx 的各位数码之和)的正整数 xx 中,求 f(2x)f(2x) 的最大值 MmaxM_{\max},以及使得 f(2x)=Mmaxf(2x) = M_{\max} 的最小 xx

    💡 解题思路

    1. 题目分析:核心是研究"乘以 2"对数码和的影响。当 xx 逐位乘以 2 时,若某一位产生进位(2×di102 \times d_i \ge 10),会导致该位的数码和贡献比"无进位"少 9。因此 f(2x)2f(x)=2Nf(2x) \le 2 \cdot f(x) = 2N,等号成立当且仅当所有位都不产生进位,即 xx 的每一位数字都 4\le 4

    2. 算法推导

      • MmaxM_{\max}:既然 f(2x)2Nf(2x) \le 2N 且我们可以通过让 xx 只含数字 040 \sim 4 来达到 2N2N(无进位),所以 Mmax=2NM_{\max} = 2N
      • xminx_{\min}:在"每一位 4\le 4"的约束下,为了最小化 xx 的数值,需要位数尽可能少(即每位尽可能大)。最大允许的数字是 44,因此贪心地用尽可能多的 44 来凑 NN
        • N=4q+rN = 4q + r,其中 0r<40 \le r < 4
        • r>0r > 0xminx_{\min}rr 后面接 qq44
        • r=0r = 0xminx_{\min}qq 个连续的 44
      • 此构造与 std.cpp 完全一致:先输出余数 rr(如果非零),再循环输出 qq44
    3. 边界与细节

      • NN 较小时(如 N=1,2,3N=1,2,3),xminx_{\min} 就是 NN 本身,无 44 后缀。
      • NN44 的倍数时,xminx_{\min} 全是 44,没有前导余数。
      • 结果可能极大(N=100N=100xminx_{\min} 有 25 位),需用字符串或直接输出,不能用 64 位整数存储。std.cpp 中逐位 cout 输出,避免了溢出问题。

    ⏱️ 复杂度分析

    • 时间复杂度O(N)O(N)。输出 MmaxM_{\max}O(1)O(1),输出 xminx_{\min} 最多输出 N/4+1\lfloor N/4 \rfloor + 1 个数字,即 O(N)O(N) 个字符。
    • 空间复杂度O(1)O(1)。仅使用常数个变量 n, x

    💻 标准代码 (C++)

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	int n;
    	cin >> n;
    	// M_max = 2N:无进位时 f(2x) 达到理论上界
    	int x = (n / 4) * 8 + (n % 4) * 2; // 等价于 2 * n
    	cout << x << '\n';
    	// 构造最小 x:先输出余数 r(1/2/3),再输出 q 个 4
    	if (n % 4) cout << n % 4;          // 输出高位余数位
    	while (n >= 4) {
    		cout << 4;                     // 每位 4 保证无进位且位数最少
    		n -= 4;
    	}
    	return 0;
    }
    

    信息

    ID
    874
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    1
    上传者