F - Maximum Sum of Digits

本文探讨了如何在给定正整数n的情况下,找到两个整数a和b,使得a+b=n且a和b的十进制表示中各数字之和最大。通过巧妙调整数字的分布,可以实现这一目标,例如将最高位的数字拆分,以增加9的出现次数,从而提高总和。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

You are given a positive integer nn.

Let S(x)S(x) be sum of digits in base 10 representation of xx, for example, S(123)=1+2+3=6S(123)=1+2+3=6, S(0)=0S(0)=0.

Your task is to find two integers a,ba,b, such that 0≤a,b≤n0≤a,b≤n, a+b=na+b=n and S(a)+S(b)S(a)+S(b) is the largest possible among all such pairs.

Input

The only line of input contains an integer nn (1≤n≤1012)(1≤n≤1012).

Output

Print largest S(a)+S(b)S(a)+S(b) among all pairs of integers a,ba,b, such that 0≤a,b≤n0≤a,b≤n and a+b=na+b=n.

Examples

Input

35

Output

17

Input

10000000000

Output

91

Note

In the first example, you can choose, for example, a=17a=17 and b=18b=18, so that S(17)+S(18)=1+7+1+8=17S(17)+S(18)=1+7+1+8=17. It can be shown that it is impossible to get a larger answer.

In the second test example, you can choose, for example, a=5000000001a=5000000001 and b=4999999999b=4999999999, with S(5000000001)+S(4999999999)=91S(5000000001)+S(4999999999)=91. It can be shown that it is impossible to get a larger answer.

 

思路:如果想明白了,其实很简单。最大的个位数是9,那么对于一个整an=a+b,不妨把最高位a单独拉出来,然后减1,将1加到b上,这样a出现了最多个数的9,整体也就出现了多个9.

例如n=123;a=100,b=23;    a-1=99;b+1=24;

sum=9+9+2+4=24;

知道了思路,代码就很好写了。

提示:我用的是long long int 读取的n,也可以使用字符串。当用字符串的时候,char n[12];while(~scanf("%s",n))

代码如下;

 

#include <stdio.h>
#include <string.h>
typedef long long int ll;
int main()
{
ll a,b,sum,n;
ll i;
//得到n的最大位数 
while(scanf("%lld",&n)!=EOF)
{
sum=
0;
for(i=1000000000000;i>=1;i=i/10)
{

if(n/i!=0)
{
a=(n/i)*i
-1;
b=n%i+
1;
for(;i>=1;i=i/10)
{
sum+=a/i+b/i;
a=a%i;
b=b%i;
}

break;

}
}

printf("%d\n",sum);
}
}


 

 

An array can be used to store large integers one digit at a time. For example, the integer 1234 could be stored in the array a by setting a[0] to 1, a[1] to 2, a[2] to 3, and a[3] to 4. However, for this exercise you might find it more useful to store the digits backward, that is, place 4 in a[0], 3 in a[1], 2 in a[2], and 1 in a[3]. In this exercise you will write a program that reads in two positive integers that are 20 or fewer digits in length and then outputs the sum of the two numbers. Your program will read the digits as values of type char so that the number 1234 is read as the four characters '1', '2', '3', and '4'. After they are read into the program, the characters are changed to values of type int. The digits will be read into a partially filled array, and you might find it useful to reverse the order of the elements in the array after the array is filled with data from the keyboard. (Whether or not you reverse the order of the elements in the array is up to you. It can be done either way, and each way has its advantages and disadvantages.) Your program will perform the addition by implementing the usual paper-and-pencil addition algorithm. The result of the addition is stored in an array of size 20, and the result is then written to the screen. If the result of the addition is an integer with more than the maximum number of digits (that is, more than 20 digits), then your program should issue a message saying that it has encountered “integer overflow.You should be able to change the maximum length of the integers by changing only one globally defined constant. Include a loop that allows the user to continue to do more additions until the user says the program should end.我是一名cpp初学者,请翻译并为我解答
03-26
.include "io32.inc" .intel_syntax noprefix .data msg_prompt: .asciz "Enter a decimal digit string (max 20 digits): " msg_prompt_len = . - msg_prompt - 1 msg_max: .asciz "Maximum digit: " msg_max_len = . - msg_max - 1 msg_min: .asciz "Minimum digit: " msg_min_len = . - msg_min - 1 msg_sum: .asciz "Sum of digits: " msg_sum_len = . - msg_sum - 1 msg_product: .asciz "Product of max and min: " msg_product_len = . - msg_product - 1 newline: .byte 10, 0 newline_len = 1 input_buf: .space 22 # 20 digits + newline + null max_digit: .byte 0 min_digit: .byte 0 digit_sum: .long 0 product: .long 0 .text .global _start _start: # 显示输入提示 mov eax, 4 # sys_write mov ebx, 1 # stdout mov ecx, offset msg_prompt mov edx, msg_prompt_len int 0x80 # 读取输入字符串 mov eax, 3 # sys_read mov ebx, 0 # stdin mov ecx, offset input_buf mov edx, 21 # 读取最大21字符 int 0x80 # 移除换行符 push offset input_buf call remove_newline add esp, 4 # 处理数字并计算结果 push offset input_buf call process_digits add esp, 4 # 输出最大数字 mov eax, 4 # sys_write mov ebx, 1 # stdout mov ecx, offset msg_max mov edx, msg_max_len int 0x80 movzx eax, byte ptr [max_digit] push eax call print_char add esp, 4 call print_newline # 输出最小数字 mov eax, 4 # sys_write mov ebx, 1 # stdout mov ecx, offset msg_min mov edx, msg_min_len int 0x80 movzx eax, byte ptr [min_digit] push eax call print_char add esp, 4 call print_newline # 输出数字和 mov eax, 4 # sys_write mov ebx, 1 # stdout mov ecx, offset msg_sum mov edx, msg_sum_len int 0x80 push dword ptr [digit_sum] call print_number add esp, 4 call print_newline # 输出乘积 mov eax, 4 # sys_write mov ebx, 1 # stdout mov ecx, offset msg_product mov edx, msg_product_len int 0x80 push dword ptr [product] call print_number add esp, 4 call print_newline # 退出程序 mov eax, 1 # sys_exit xor ebx, ebx int 0x80 # 子程序:移除换行符 remove_newline: push ebp mov ebp, esp mov esi, [ebp+8] # 输入字符串地址 remove_loop: mov al, [esi] test al, al jz end_remove cmp al, 10 # 换行符ASCII=10 je found_newline inc esi jmp remove_loop found_newline: mov byte ptr [esi], 0 end_remove: pop ebp ret # 子程序:处理数字字符串 process_digits: push ebp mov ebp, esp push esi push ebx mov esi, [ebp+8] # 输入字符串地址 mov dword ptr [digit_sum], 0 # 数字和归零 mov ecx, 0 # 有效数字计数器 # 初始化min_digit为9,max_digit为0 mov byte ptr [min_digit], '9' mov byte ptr [max_digit], '0' process_loop: mov al, [esi] test al, al jz end_process # 检查是否为数字(ASCII 48-57) cmp al, '0' jb next_char cmp al, '9' ja next_char # 更新最小值 cmp al, [min_digit] jae check_max mov [min_digit], al check_max: # 更新最大值 cmp al, [max_digit] jbe update_sum mov [max_digit], al update_sum: # 累加数字和 sub al, '0' # 字符转数字 movzx eax, al add [digit_sum], eax inc ecx # 检查是否超过20个数字 cmp ecx, 20 jae end_process next_char: inc esi jmp process_loop end_process: # 计算乘积:max × min mov al, [max_digit] sub al, '0' mov bl, [min_digit] sub bl, '0' mul bl mov [product], eax pop ebx pop esi pop ebp ret # 子程序:打印字符 print_char: push ebp mov ebp, esp sub esp, 4 # 为局部变量分配空间 # 将字符存入局部变量 mov al, byte ptr [ebp+8] mov byte ptr [ebp-4], al # 系统调用输出字符 mov eax, 4 # sys_write mov ebx, 1 # stdout lea ecx, [ebp-4] # 字符地址 mov edx, 1 # 输出长度=1 int 0x80 add esp, 4 # 清理栈空间 pop ebp ret # 子程序:打印换行 print_newline: mov eax, 4 # sys_write mov ebx, 1 # stdout mov ecx, offset newline mov edx, newline_len int 0x80 ret # 子程序:打印数字(递归实现) print_number: push ebp mov ebp, esp mov eax, [ebp+8] # 获取数字 # 处理0特殊情况 test eax, eax jnz not_zero push '0' call print_char add esp, 4 jmp end_print not_zero: # 递归打印高位数字 xor edx, edx mov ecx, 10 div ecx # eax=商, edx=余数 test eax, eax jz skip_recursion push eax call print_number add esp, 4 skip_recursion: # 打印当前位 add edx, '0' push edx call print_char add esp, 4 end_print: pop ebp ret 修改代码
06-11
.include "io32.inc" .intel_syntax noprefix .data msg_prompt: .asciz "Enter a decimal digit string (max 20 digits): " msg_max: .asciz "Maximum digit: " msg_min: .asciz "Minimum digit: " msg_sum: .asciz "Sum of digits: " msg_product: .asciz "Product of max and min: " newline: .byte 10, 0 input_buf: .space 22 # 20 digits + newline + null max_digit: .byte 0 min_digit: .byte 0 digit_sum: .long 0 product: .long 0 format_char: .asciz "%c" format_int: .asciz "%d" .text .global _main .extern _printf .extern _fgets .extern _exit _main: # 提示输入 push offset msg_prompt call _printf add esp, 4 # 读取输入 (stdin = 0) push 0 push 21 # 20+1 个字符 push offset input_buf call _fgets add esp, 12 # 处理数字串 push offset input_buf call process_digits add esp, 4 # 输出结果 call output_results # 退出程序 push 0 call _exit # 移除换行符 remove_newline: push ebp mov ebp, esp mov esi, [ebp+8] # 输入缓冲区地址 remove_loop: lodsb test al, al jz end_remove cmp al, 10 # 换行符 jne remove_loop mov byte ptr [esi-1], 0 end_remove: mov esp, ebp pop ebp ret # 处理数字串 (核心算法) process_digits: push ebp mov ebp, esp push esi push ebx mov esi, [ebp+8] # 输入字符串地址 call remove_newline # 清理换行符 # 初始化最小值和最大值 mov byte ptr [min_digit], '9' mov byte ptr [max_digit], '0' mov dword ptr [digit_sum], 0 xor ecx, ecx # 数字计数器 process_loop: mov al, [esi] test al, al jz end_process # 检查数字有效性 (ASCII 48-57) cmp al, '0' jb skip_char cmp al, '9' ja skip_char # 更新最大值: $max = \max(max, current)$ cmp al, [max_digit] jbe check_min mov [max_digit], al check_min: # 更新最小值: $min = \min(min, current)$ cmp al, [min_digit] jae calc_sum mov [min_digit], al calc_sum: # 计算数字和: $\sum digit_i$ sub al, '0' movzx eax, al add [digit_sum], eax inc ecx cmp ecx, 20 # 最多处理20个数字 skip_char: inc esi jmp process_loop end_process: # 计算乘积: $prod = (max - '0') \times (min - '0')$ mov al, [max_digit] sub al, '0' mov bl, [min_digit] sub bl, '0' mul bl mov [product], eax pop ebx pop esi mov esp, ebp pop ebp ret # 输出结果集 output_results: # 最大值 push offset msg_max call _printf add esp, 4 movzx eax, byte ptr [max_digit] push eax call print_char add esp, 4 call print_newline # 最小值 push offset msg_min call _printf add esp, 4 movzx eax, byte ptr [min_digit] push eax call print_char add esp, 4 call print_newline # 数字和 push offset msg_sum call _printf add esp, 4 push dword ptr [digit_sum] call print_number add esp, 4 call print_newline # 乘积 push offset msg_product call _printf add esp, 4 push dword ptr [product] call print_number add esp, 4 jmp print_newline # 链式调用 # 打印字符 print_char: push ebp mov ebp, esp push dword ptr [ebp+8] push offset format_char call _printf add esp, 8 pop ebp ret # 打印整数 print_number: push ebp mov ebp, esp push dword ptr [ebp+8] push offset format_int call _printf add esp, 8 pop ebp ret # 打印换行 print_newline: push offset newline call _printf add esp, 4 ret 加上从键盘输入字符串
最新发布
06-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值