Maximum Sum of Digits

本文探讨了在给定整数n的情况下,寻找两个整数a和b,使得a+b=n且a和b的数字和最大的问题。通过预处理9的幂次序列,算法能够快速找到接近n的最大数字,然后计算其数字和。

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

https://ac.nowcoder.com/acm/contest/877/K

题意:n;a+b=n,找a,b使得他们的数字和最大;

思路:处理除9,99,999,9999....减去最大的算就行,一开始处理9,19,199...脑抽:(

#include<algorithm>
#include<set>
#include<vector>
#include<queue>
#include<cmath>
#include<cstring>
#include<iostream>
#include<set>
#include<vector>
#include<queue>
#include<cmath>
#include<cstdio>
#include<map>
#include<stack>
#include<string>
#include<bits/stdc++.h>
using namespace std;

#define sfi(i) scanf("%d",&i)
#define pri(i) printf("%d\n",i)
#define sff(i) scanf("%lf",&i)
#define ll long long
#define ull unsigned long long
#define mem(x,y) memset(x,y,sizeof(x))
#define INF 0x3f3f3f3f
#define eps 1e-16
#define PI acos(-1)
#define lowbit(x) ((x)&(-x))
#define zero(x) (((x)>0?(x):-(x))<eps)
#define fl() printf("flag\n")
#define MOD(x) ((x%mod)+mod)%mod
#define endl '\n'
#define pb push_back
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
ll gcd(ll a,ll b){while(b^=a^=b^=a%=b);return a;}
const int maxn=1e6+9;
const int mod=1e9+7;

inline ll read()
{
    ll f=1,x=0;
    char ss=getchar();
    while(ss<'0'||ss>'9')
    {
        if(ss=='-')f=-1;ss=getchar();
    }
    while(ss>='0'&&ss<='9')
    {
        x=x*10+ss-'0';ss=getchar();
    }    return f*x;
}

ll num[100];
int main()
{
    //FAST_IO;
    //freopen("input.txt","r",stdin);

    int cnt=0;
    num[cnt++]=9;
    ll now=9;
    for(int i=1;i<14;i++)
    {
        num[cnt++]=now*10+9;
        now=now*10+9;
    }
    //for(int i=0;i<cnt;i++) cout<<num[i]<<" ";
    int t;
    cin>>t;
    while(t--)
    {
        ll n;
        ll ans=0;
        cin>>n;
        int pos=lower_bound(num,num+cnt,n)-num;
        if(num[pos]>n)pos--;
        ll k=n-num[pos];
       // cout<<num[pos]<<" "<<k<<endl;
        while(k)
        {
            ans=ans+k%10;
            k/=10;
        }
        ll tmp=num[pos];
        while(tmp)
        {
            ans+=tmp%10;
            tmp/=10;
        }
        cout<<ans<<endl;
    }
    return 0;
}

 

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_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
.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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值