输入一个N,输出所有拆分的方式。
例如输入3,输出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输出结果。
C语言描述:
#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; scanf("%d", &n); divN(n, 1); 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
运行结果: