7.3.1. Написать программу, которая печатает по одному разу все
последовательности длины n, составленные из чисел
(их количество равно
).
procedure generate;
| var i,j : integer;
begin
| if t = n then begin
| | for i:=1 to n do begin
| | | write(a[i]);
| | end;
| | writeln;
| end else begin {t < n}
| | for j:=1 to k do begin
| | | t:=t+1;
| | | a[t]:=j;
| | | generate;
| | | t:=t-1;
| | end;
| end;
end;
Основная программа теперь состоит из двух операторов:
t:=0; generate;`
Замечание. Команды t:=t+1 и t:=t-1 для экономии можно вынести из цикла for.
7.3.2. Написать программу, которая печатала бы все перестановки
чисел
по одному разу.
for i:=1 to n do begin a[i]:=i; end;
t:=0;
generate;
Вот описание процедуры:
procedure generate;
| var i,j : integer;
begin
| if t = n then begin
| | for i:=1 to n do begin
| | | write(a[i]);
| | end;
| | writeln;
| end else begin {t < n}
| | for j:=t+1 to n do begin
| | | поменять местами a[t+1] и a[j]
| | | t:=t+1;
| | | generate;
| | | t:=t-1;
| | | поменять местами a[t+1] и a[j]
| | end;
| end;
end;`
7.3.3. Напечатать все возрастающие последовательности длины k,
элементами которых являются натуральные числа от 1 до n.
(Предполагается, что
, иначе таких
последовательностей не существует.)
procedure generate;
| var i: integer;
begin
| if t = k then begin
| | печатать a[1]..a[k]
| end else begin
| | t:=t+1;
| | for i:=a[t-1]+1 to t-k+n do begin
| | | a[t]:=i;
| | | generate;
| | end;
| | t:=t-1;
| end;
end;`
Замечание. Цикл for мог бы иметь верхней границей n
(вместо Основная программа теперь выглядит так:
t:=1;
for j:=1 to 1-k+n do begin
| a[1]:=j;
| generate;
end;
Можно было бы добавить к массиву a слева фиктивный элемент
7.3.4. Перечислить все представления положительного целого числа
n в виде суммы последовательности невозрастающих целых
положительных слагаемых.
procedure generate;
| var i: integer;
begin
| if s = n then begin
| | печатать последовательность a[1]..a[t]
| end else begin
| | for i:=1 to min(a[t], n-s) do begin
| | | t:=t+1;
| | | a[t]:=i;
| | | s:=s+i;
| | | generate;
| | | s:=s-i;
| | | t:=t-1;
| | end;
| end;
end;
Основная программа при этом может быть такой:
t:=1;
for j:=1 to n do begin
| a[1]:=j
| s:=j;
| generate;
end;`
Замечание. Можно немного сэкономить, вынеся операции увеличения и уменьшения
t:=0; s:=0; a[0]:=n; generate;
7.3.5. Написать рекурсивную программу обхода дерева (используя те
же команды и проверки, что и в главе про обход дерева).
обработать_над обрабатывает все
листья над текущей вершиной и заканчивает работу в той же
вершине, что и начала. Вот ее рекурсивное описание:
procedure обработать_над;
begin
| if есть_сверху then begin
| | вверх_налево;
| | обработать_над;
| | while есть_справа do begin
| | | вправо;
| | | обработать_над;
| | end;
| | вниз;
| end else begin
| | обработать;
| end;
end;`