回 帖 发 新 帖 刷新版面

主题:关于数字拆分(数学很浓)

问题描述:120以内的数,拆分成n个自然数的和,求n的个数,要求用过程实现
我这儿的一种做法不是很明白,望高人指点,如果有其他方法,请不吝赐教
(n是自然数,c存放个数变量)
var n:byte;c:longint;
function min(x,y:integer):integer;    {定义取两数种小些的数的函数}
begin 
 if x<y then min:=x else min:=y;
end;
procedure work(sy,kc:byte);       
var i:byte;
begin
 for i:=min(sy,kc) downto 1 do                 {此处甚难理解}
   if i=sy then c:=c+1 else work(sy-i,i);
end;
begin
readln(n);
work(n,n);
writeln(c);
end.

回复列表 (共5个回复)

沙发

递归...

板凳

我知道是递归,但不知如何,看不明白

3 楼

递归法是?不懂

4 楼

其他方法
分析:
等式中后一个数必须大于等于前一个数,因为这个可以1、避免重复2提高效率

我们用一个数组a[i]来记录拆分的数字,用b[i]记录剩下的数字。K记录第几个拆分的数字。每次拆分都可以把a[i]都打印出来。

把剩下的数字b[i]在进行拆分,并且是从i开始拆分的。Find(b[i],i,k+1)


program cf;
var a,b:array[1..100] of integer;
    n,i:integer;

procedure find(start,m,k:integer);
{从start开始,对m进行拆分,拆分是第k个数}
var i,j:integer;
begin


   for i:=start to (m div 2) do    {只要从start 到m的一个半,可以避免重复}
     begin
         write(n,'=');
        a[k]:=i;b[k]:=m-i;
        for j:=1 to k do write(a[j],'+');
        writeln(b[k]);
        find(i,b[k],k+1);
     end;

end;

begin
assign(input,'word.in');
assign(output,'word.out');
reset(input);
rewrite(output);
readln(n);

find(1,n,1);

close(input);
close(output);
end.


5 楼

呵呵~~
是辗转相除法拉....
具体可在网上搜有关帖哦
晕~~~~

我来回复

您尚未登录,请登录后再回复。点此登录或注册