问题描述
输入一个N,输出所有拆分的方式。
如input: 3
output:
1+1+1
1+2
3
算法思想
用一个数组res[]存放拆分的解,用全局变量存放拆分的方法数。
divN(n,k)使用n表示要分解的整数,k表示res数组下标,即第k次拆分。
先从divN(n,1)开始,用num表示第k个拆分的数,即res[k]=num,
让num在[1,n]内遍历。用rest=n-num表示拆分后剩下的整数值。若rest等于零,
代表本次拆分结束,输出拆分解。否则处理第k+1个数组元素,即divN(rest,k+1),
依次类推,直到rest为0输出结果。
源代码
#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
int res[10000] = { 0 }; //res数组存放解
int times = 0; //times计算拆分的次数
void divN(int n, int k) { //n是需要拆分的整数,k是指res数组的下标
int rest; //存放拆分后剩余的整数
for (int num = 1;num <= n; num++) { //从1开始尝试拆分
if (num >= res[k - 1] ) { //拆分的解要大于或等于前一个解保证不重复
res[k] = num; //将这次拆分存放在res数组中
rest = n - num; //剩下的是n-num
if (rest == 0) { //如果没有剩下的,说明本次拆分结束
times++; //拆分次数加1
printf("%3d:", times);
for (int j = 1; j < k; j++) { //输出解
printf("%d+", res[j]);
}
printf("%d\n", res[k]);
}
else divN(rest, k + 1); //如果有剩下的,继续求出res[k+1]
}
}
}
int main() {
int n;
printf("Please enter a integer N:");
scanf_s("%d", &n);
divN(n, 1);
printf("there are %d ways to divide the integer %d.", times,n);
system("pause");
return 0;
}
汇编代码
INCLUDE Irvine32.inc
.data
s1 db 'Please enter a integer N:',0
s2 db 'there are',0
s3 db 'ways to divide the integer',0
res dd 40000 dup(?)
times dd 0
n dd 0
.code
main PROC
mov edx,offset s1
call writestring
call readInt
mov n,eax
mov ecx,1
push ecx
push eax
call divN
call outres
exit
main ENDP
divN PROC
push ebp
mov ebp,esp
pushad
mov ecx,[ebp+8] ;ecx:n
mov ebx,[ebp+12] ;ebx:k
mov esi,0 ;esi:rest
mov edx,offset res ;edx:res[]
mov edi,1 ;edi:num
again:
cmp edi,ecx
jg final
cmp edi,[edx+ebx*4-4]
jl final
mov [edx+ebx*4],edi
mov eax,ecx
sub eax,edi
mov esi,eax
cmp esi,0
jne next
add times,1
next1:
; mov eax,times
; call writedec
push ebx
call output
next:
inc ebx
; mov eax,ebx
; call writedec
; call crlf
push ebx
push esi
call divN
dec ebx
inc edi
jmp again
final:
popad
pop ebp
ret 8
divN ENDP
output PROC
push ebp
mov ebp,esp
pushad
mov edx, offset res ;edx:res
mov edi,[ebp+8] ;edi:k
mov esi,1 ;esi:j
again:
cmp esi,edi
jge final
mov eax,[edx+esi*4]
call writedec
mov al,'+'
call writechar
inc esi
jmp again
final:
mov eax,[edx+edi*4]
call writedec
call crlf
popad
pop ebp
ret 4
output ENDP
outres PROC
push ebp
mov ebp,esp
pushad
mov edx,offset s2
call writeString
mov al,' '
call writechar
mov eax,times
call writedec
mov al,' '
call writechar
mov edx,offset s3
call writestring
mov al,' '
call writechar
mov eax,n
call writedec
call crlf
popad
pop ebp
ret
outres ENDP
END main