TIMUS 1014. Product of Digits

本文介绍了一个算法问题的解决方案,即找到最小的正整数,其各位数字的乘积等于给定的整数N。特别地,文章提供了一段Java代码实现,并讨论了特殊情况,例如当N为0时的正确处理方式。
题目如下:
Your task is to find the minimal positive integer number Q so that the product of digits of Q is exactly equal to N.

Input

The input contains the single integer number N (0 ≤ N ≤ 109).

Output

Your program should print to the output the only number Q. If such a number does not exist print −1.

Sample

inputoutput
10
25

 

 

 

题目比较简单,求各位数相乘等于给定数的最小数。 要注意给0的情况,按题意,结果不是0也不是-1,而是10,因为这个错了WE N次。

 

 

代码:

.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
本系统旨在构建一套面向高等院校的综合性教务管理平台,涵盖学生、教师及教务处三个核心角色的业务需求。系统设计着重于实现教学流程的规范化与数据处理的自动化,以提升日常教学管理工作的效率与准确性。 在面向学生的功能模块中,系统提供了课程选修服务,学生可依据培养方案选择相应课程,并生成个人专属的课表。成绩查询功能支持学生查阅个人各科目成绩,同时系统可自动计算并展示该课程的全班最高分、平均分、最低分以及学生在班级内的成绩排名。 教师端功能主要围绕课程与成绩管理展开。教师可发起课程设置申请,提交包括课程编码、课程名称、学分学时、课程概述在内的新课程信息,亦可对已开设课程的信息进行更新或撤销。在课程管理方面,教师具备录入所授课程期末考试成绩的权限,并可导出选修该课程的学生名单。 教务处作为管理中枢,拥有课程审批与教学统筹两大核心职能。课程设置审批模块负责处理教师提交的课程申请,管理员可根据教学计划与资源情况进行审核批复。教学安排模块则负责全局管控,包括管理所有学生的选课最终结果、生成包含学号、姓名、课程及成绩的正式成绩单,并能基于选课与成绩数据,统计各门课程的实际选课人数、最高分、最低分、平均分以及成绩合格的学生数量。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值