#P2663. 第1题-数位操作
-
1000ms
Tried: 128
Accepted: 35
Difficulty: 3
所属公司 :
阿里
时间 :2025年3月8日-阿里淘天(算法岗)
-
算法标签>暴力枚举
第1题-数位操作
1. 题面描述
小红有一个正整数n,我们记w(n)为 n 的数位之和(即把 n 每一位上的数字相加)。例如:
[
w(123) = 1 + 2 + 3 = 6
]
小红可以进行的操作是:
- x→x+1,或者
- x→x−1,
在整个操作过程中,要求中间的数字始终保持大于 0(即 x>0)。小红最多可以进行 k 次这样的操作。
问:在不超过 k 次操作的情况下,可以得到的某个数字 m 的数位和 w(m) 的最大值是多少?
2. 思路分析
-
目标:最大化 m 的数位和 w(m)。
-
可行操作:每次只能做 +1 或 −1。
-
限制:不超过 k 次操作,且过程中数字始终大于 0。
-
可达范围:
- 若最终数字是 m,则必然满足 ∣m−n∣≤k。
- 而且 m≥1。
也就是说,我们能在区间 [max(1,n−k),n+k] 之内找到任意一个候选 m,都能用不超过 k 次加减操作实现(并保证不出现 ≤0 的中间状态,如果我们不做多余的操作)。
-
直接枚举:
- 我们可以枚举所有 m 从 max(1,n−k) 到 n+k。
- 对每个 m 计算其数位和 w(m),并记录最大值。
- 在最坏情况下,k 最大可达 106,那么需要枚举的 m 数量最多在 2×106 左右,乘上计算数位和的复杂度,仍在可接受范围内(尤其在 C++ 等语言中)。
C++ 代码
#include <bits/stdc++.h>
using namespace std;
// 计算一个正整数 x 的数位和
int digitSum(long long x) {
int sum = 0;
while (x > 0) {
sum += x % 10;
x /= 10;
}
return sum;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
long long n, k;
cin >> n >> k;
// 枚举的下界(不能小于 1)
long long start = max(1LL, n - k);
// 枚举的上界
long long end = n + k;
int ans = 0; // 记录数位和的最大值
for (long long m = start; m <= end; m++) {
int w_m = digitSum(m);
if (w_m > ans) {
ans = w_m;
}
}
cout << ans << "\n";
return 0;
}
Python
# 计算一个正整数 x 的数位和
def digit_sum(x):
sum_digits = 0
while x > 0:
sum_digits += x % 10
x //= 10
return sum_digits
def main():
n, k = map(int, input().split())
# 枚举的下界(不能小于 1)
start = max(1, n - k)
# 枚举的上界
end = n + k
ans = 0 # 记录数位和的最大值
for m in range(start, end + 1):
w_m = digit_sum(m)
if w_m > ans:
ans = w_m
print(ans)
if __name__ == "__main__":
main()
7. Java
import java.util.Scanner;
public class Main {
// 计算一个正整数 x 的数位和
public static int digitSum(long x) {
int sum = 0;
while (x > 0) {
sum += (x % 10);
x /= 10;
}
return sum;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long n = sc.nextLong();
long k = sc.nextLong();
sc.close();
// 枚举的下界(不能小于 1)
long start = Math.max(1, n - k);
// 枚举的上界
long end = n + k;
int ans = 0;
for (long m = start; m <= end; m++) {
int w_m = digitSum(m);
if (w_m > ans) {
ans = w_m;
}
}
System.out.println(ans);
}
}
题目内容
小红有一个正整数数字n,我们记w(n)为n的数位之和,例如 w(123)=6。
每次操作x→x+1或者x→x−1,其操作过程需要保证n>0。
小红想知道在不超过k次操作的前提下,得到的数字m的w(m)最大是多少?
输入描述
两个数字n,k(1≤n≤109,1≤k≤106)。
输出描述
一个整数,表示w(m)的最大值。
样例1
输入
3 5
输出
8