拆分自然数N之和

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

【拆分自然数N之和】

任何一个大于1的自然数n,总可以拆分成若干个小于n的自然数之和。(n<=100)

【样例】

输入n=7

输出:

7=1+6

7=1+1+5

7=1+1+1+4

7=1+1+1+1+3

7=1+1+1+1+1+2

7=1+1+1+1+1+1+1

7=1+1+1+2+2

7=1+1+2+3

7=1+2+4

7=1+2+2+2

7=1+3+3

7=2+5

7=2+2+3

7=3+4

【分析过程】:

1.10=3+7与10=7+3 是同一个拆分。(避免重复,只要让前面的加数≤后面的加数)

2.n=7.

第一步,将N拆分为2项之和:

7=1+6

7=2+5

7=3+4

(不能拆)

其中对它进行继续拆分

.

【如何用算法实现】

用数组a[0..100],a[k]中存储已完成的一种拆分。比如:7=1+6。可以用数组a表示:a[0]=7,a[1]=1,a[2]=6,k=2,继续拆分从a[k](从a[2] 开始);a[k]能否再次拆分取决于a[k] div 2 是否大于或等于a[k-1];在这里,我们采取的回溯(递归)过程中有两个元素:nx表示要拆分的数值大小,kx表示接着要拆的那个数的下标,nx存储在数组元素a[kx]中,即a[kx]=nx。

参考程序:

var

n,i,j:integer;

a:array[0..100] of integer;

procedure sum(nx,kx:integer);

var

k,m,l:integer;

begin

j:=j+1;

write('Sum No.',j:3,':',a[0],'='); {输出标头,可以根据题目具体要求删或修改}

for k:=1 to kx-1 do

write(a[k],'+'); {输出前面的加数}

writeln(a[kx]); {输出最后一个加数并换行}

k:=kx;//保存当前要拆分数的下标

l:=a[k]; {第一组拆分结束,l是替身,后面要计算相差部分}

for m:=a[k-1] to l div 2 do {新赋值的拆分范围,因为不能大于前一个加数,所以初值是前一个加数}

begin

a[k]:=m;

a[k+1]:=l-m; {新赋值初始化拆分}

sum(a[k+1],k+1); {回溯下一个}

end;

end;

begin

read(a[0]);

j:=0;

if a[0]>=2 then {a[0]>=2时才有数据可以拆分}

for i:=1 to a[0] div 2 do {第一个加数的拆分范围}

begin

a[1]:=i;

a[2]:=a[0]-a[1]; {初始化拆分}

sum(a[0],2); {调用sum}

end; {when a[0]>2}

writeln;

end.

相关文档
最新文档