1 条题解

  • 0
    @ 2026-6-19 10:30:17

    📝 题目大意

    给定非负整数 XX 和操作次数 KK,依次对 i=0,1,,K1i = 0, 1, \dots, K-1 执行操作:将 XX 四舍五入到最近的 10i+110^{i+1} 的倍数,若距离相等则取较大的那个。输出最终结果。

    💡 解题思路

    1. 题目分析

      • 0X<10150 \le X < 10^{15}1K151 \le K \le 15,数据范围较小,模拟即可。
      • 每一步的舍入单位是 10i+110^{i+1},即对第 ii 位(从 10010^0 开始)进行四舍五入。
      • 注意 XX 最大可能达到 101510^{15},需要 64 位整数(long long)。
    2. 算法推导

      • 对于第 ii 步(ii00 开始),舍入单位 x=10i+1x = 10^{i+1}
      • a=nx×xa = \lfloor \frac{n}{x} \rfloor \times x(下界倍数),b=a+xb = a + x(上界倍数)。
      • n<a+b2n < \frac{a+b}{2}2n<a+b2n < a+b 时,nn 更靠近 aa,向下舍入为 aa;否则向上舍入为 bb
      • 注意 n=a+b2n = \frac{a+b}{2} 时,2n=a+b2n = a+b,不等式不成立,走 else 分支取 bb,满足"距离相等时取较大值"的要求。
      • 循环 KK 次,每次更新 nn,最后输出 nn
    3. 边界与细节

      • X=0X=0 时,无论 KK 多大,n/x=0n/x = 0a=0a=02n=0<b2n=0 < b,始终取 a=0a=0,结果恒为 00
      • KK 足够大使得 10KX10^{K} \gg X 时,XX 会被舍入为 00(如样例 2:X=1,K=15X=1, K=15)。
      • 使用 long long 避免溢出,pow(10, i+1) 返回 double,在 i14i \le 14 时精度足够。

    ⏱️ 复杂度分析

    • 时间复杂度O(K)O(K),每次迭代 O(1)O(1)K15K \le 15
    • 空间复杂度O(1)O(1),仅使用常数个变量。

    💻 标准代码 (C++)

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long          // 数据范围可能超过 32 位,统一使用 long long
    signed main()
    {
    	int n, k;
    	scanf("%lld%lld", &n, &k);
    	for (int i = 0; i < k; i++)
    	{
    		int x = pow(10, i + 1);           // 第 i 步的舍入单位:10^{i+1}
    		int a = n / x * x;                // 下界:不大于 n 的最近 x 的倍数
    		int b = n / x * x + x;            // 上界:a + x
    		if (n * 2 < a + b)                // n 更靠近 a,向下舍入
    			n = a;
    		else                              // n 更靠近 b 或等距,向上舍入
    			n = b;
    	}
    	printf("%lld\n", n);
    	return 0;
    }
    
    • 1

    信息

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