program generuj1;
{ Generovani rozkladu cisla na soucet prirozenych cisel oddelenych znamenkem +, kazdy na samostatnou radku.
Na poradi scitancu zalezi, tedy 1 + 2 je neco jineho nez 2 + 1. }
const max=1000; { Víme, že počet sčítanců <= číslo na vstupu <= 1000. }
var cislo:integer;
pole:array[1..max] of integer; { Do pole budeme zapisovat jednotlive scitance. Vzdy, kdyz jejich soucet je
roven cislu ze vstupu, scitance vypiseme.}
{ Vypíše sčítance v poli na indexech 1 až index, mezi ně vkládá +. }
procedure vypis(index:integer);
var i: integer;
begin
for i:=1 to index-1 do
write(pole[i],'+');
writeln(pole[index]);
end;
{ Vyplnuje do pole možné sčítance prvního parametru zbyva. V každé hladině rekurze se podívá, zda je ještě
co vyplňovat, tedy zbyva >= 0. Pokud ano, tak na index i postupně zkouší vyplňovat všechny možné sčítance
od 1 do zbyva. Parametry:
- zbyva: odpovídá aktuálnímu číslu, které chceme rozložit na sčítance
- i: odpovídá indexu v poli, kam máme zapsat další sčítanec. }
procedure rekurze(zbyva,i:integer);
var j:integer;
begin
{ Jestliže je zbyva=0, tak máme v poli uložené sčítance, které dávají přesně potřebný součet. }
if zbyva=0 then vypis(i-1); { Zde se zamyslete, proc volame funkci vypis s argumentem (i-1). }
{ Je-li zbyva>0, tak je ještě třeba přidat další sčítance. }
if zbyva>0 then
begin
for j:=1 to zbyva do { Další sčítanec může z rozsahu 1 až zbyva. }
begin
pole[i]:=j; { Zkusíme sčítanec j a rekurzivně se zavoláme na: }
rekurze(zbyva-j,i+1); { ...na součet o aktuální sčítanec menší a na index o 1 větší. }
end;
end;
{ Zbývající možnost je, že zbyva<0. V takovém případě jsme to už přešvihli a tato větev nemá šanci na
úspěch. Všimněte si, že v takovém případě se rovnou vracíme (v rekurzi) zpět o patro výše. }
end;
begin
read(cislo);
rekurze(cislo,1);
end.
Kdo byste našel v nějakém z těchto programů chybu, dejte mi to vědět - můžete tak získat bonusové body (1 chyba ≈ 5 bodů). ;)