- •Задания II уровня
- •Задания I уровня
- •Задания II уровня
- •Задания I уровня
- •Задания II уровня
- •Задания I уровня
- •Задания II уровня
- •Задания I уровня
- •Задания II уровня
- •Лабораторная работа
- •Лабораторная работа
- •Задания
- •Лабораторная работа
- •Описание процедур начинается со строки:
- •Задания I уровень
- •Задания II уровень:
- •Задания
- •Лабораторная работа
- •Задания
- •II уровень
- •Задания I уровень
- •Задания II уровень
- •Петров л.Л 9 9 9 Барановичи
- •Лабораторная работа
- •Задания I уровень
- •II уровень
- •Самостоятельная работа
- •Литература
Задания
I УРОВЕНЬ
1. Попробуем использовать рекурсию, выводя на экран известные строки стихотворения.
uses CRT; procedure Pop; begin { if keypressed then halt;} writeln(‘У попа была собака, он ее любил’); writeln(‘Она съела кусок мяса, он ее убил’); writeln(‘похоронил и надпись написал:’); Pop; end; Begin Pop End. |
Замечание: Программа будет работать до тех пор, пока не будет переполнен стек обращений процедуры к самой себе (ошибка 202). При рекурсивном программировании велика вероятность ошибки, поэтому стоит компилировать программу с директивами {$S+} (завершение работы программы и вывод сообщения об ошибке в случае переполнения стека) и {$R+} (включение проверки диапазона переменных). Можно в начале рекурсивной процедуры помещать строку IF KEYPRESSED THEN HALT (при зависании программы достаточно нажать любую клавишу). |
Уберите фигурные скобки ({}) и опять выполните программу, но прервите ее выполнение до того, как появится сообщение об ошибке (нажмите любую клавишу).
2. Типичной функцией, на которой объясняют рекурсию, является факториал n!=1*2*3*…*n. Он может быть описан следующим образом
Т.е. для вычисления факториала, если n>1, нужно сначала вычислить (n-1)!. А для вычисления последнего надо сначала вычислить (n-2)!. Соответственно, для вычисления (n-2)! надо знать (n-3)! и т.д. Значение 1! (0!) задается явно. В программе реализованы два метода вычисления факториала: с помощью рекурсии {*} и прямой {**} – вычислением по формуле с использованием цикла.
{ factorial n! - rekurcia} uses crt; var s:longint; n: word; function f(n:word): longint; {recursion} {*} begin if keypressed then halt; if (n=1) or (n=0) then f:=1 else f:=n*f(n-1); end; function f_iter(n:word): longint; {iterazion } {**} var i:word; fi :longint; |
begin fi:=1; for i:=1 to n do fi:=fi*i; f_iter:=fi; end; begin {осн. прогр. } write('vvedite n='); read(n);s:=f(n); writeln('recursion: factorial=',s); writeln('iterazion: factorial=',f_iter(n)); write('click <enter>'); readln;
end. |
Проверьте работу программы для n=2, 4, 9. Запишите ответы.
3. Сколько рекурсивных вызовов выполнится до того, как подпрограмма дойдет до n= 1 (выполнение действий на рекурсивном спуске)? А сколько действий выполнится после рекурсивного вызова (действия на рекурсивном возврате)?
4. Для закрепления понятия рекурсии запрограммируем вычисление n-го числа Фибоначчи также двумя методами: с использованием рекурсии и итерационным.
{fibonacci n! - rekurcion and iterazion} uses crt; var s:longint; n: word; function fib(n:word): longint; {recursion} var f:longint; begin if keypressed then halt; if (n=1) or (n=0) then fib:=1 else fib:=fib(n-1) + fib(n-2); end;
function fib_iter(n:word): longint; {iterazion } var i:word; a,b,c :longint; begin a:=1; b:=1; if (n=1) or (n=0) then fib_iter:=1 |
else begin for i:=2 to n do begin c:=a+b; a:=b; b:=c; end; fib_iter:=c; end; end; begin { основная} write('vvedite n='); read(n); write('recursion: fibonacci=',fib(n)); writeln; writeln('iterazion: fibonacci=',fib_iter(n)); write('click <enter>'); readln; end. |
Проверьте работу программы для n=2, 6, 10. Запишите ответы.
Сравните время выполнения и того и другого способа, указав n достаточно большим.
Рекурсивный алгоритм Евклида вычисления НОД:
Словами этот рекурсивный алгоритм можно выразить следующим образом. Для того, чтобы найти НОД двух чисел a и b, необходимо их сравнить. Если a=b, то НОД равен a. Если же одно из чисел больше другого, то нужно из большего вычесть меньшее, и повторно применить вышеизложенный алгоритм к паре чисел: разности большего и меньшего и меньшему из чисел. Процесс завершится, когда обачисла становятся равными.
Var a, b : longint; function NOD (a,b:longint):longint; begin if a>b then NOD := NOD(a-b,b) else if a<b then NOD := NOD (a,b-a) else NOD := a; end; |
{основная программа} begin readln (a,b); writeln (NOD (a,b)); end.
|
Замечания:
А) Просмотреть действие рекурсивного алгоритма можно с помощью режима Debug /Add watch/ и выбрать в качестве просматриваемых переменных переменную ‘n’ (можно косвенно увидеть прямой и обратный ход рекурсии) при исполнении программы пошагово (нажимая F7) в окне Watches в помощью 7F6). Например, для n=4 n будет последовательно меняться n=4,3,2,1,1,2,3,4
Б) можно в рекурсивной подпрограмме ввести дополнительные переменные, присвоить им значения этих подпрограмм и просматривать уже значения дополнительных переменных.
5. Найти сумму факториалов 1!+2!+3!+…n! c использованием рекурсии.
6. Вывести на печать все n чисел Фибоначчи
ЗАДАНИЯ II УРОВНЯ:
1. Написать рекурсивную программу вычисления n- го члена арифметической прогрессии (для вычисления n-го члена арифметической прогрессии необходимо знать значение ее предыдущего члена, первого члена и значение разности d: an=an-1+d).
2. Написать рекурсивную программу вычисления целой неотрицательной степени числа А.
По определению Аn=A*A*A*…..*A=An-1*A (n>0); А0 =1
Из определения следует, что для того, чтобы вычислить n-ю степень числа, необходимо знать значение (n-1)-й степени этого числа. Если же n=0, то значение степени равно 1.
3. Составить программу вычисления элементов последовательности, определенной следующим образом:
а(1)= 1,
а(n)= n-a(a(n-1)), n>1
Попробуйте вычислить несколько элементов этой последовательности вручную. А если просчитать с помощью компьютера 50, 100, 300 элементов?
4. Измените эту программу так, чтобы в ней использовалось рекурсивное обращение к элементам массива. Какая программа – с использованием рекурсивной функции или с рекурсивным обращением к элементам массива– быстрее?
5 Написать рекурсивную программу вычисления n-й степени числа А другим способом, например:
Аn=An/2* An/2, если n –четно;
Аn= A *A (n-1)/2 * A (n-1)/2, если n –нечетно. Проверьте вычисления для n=2.
А еще способы вычисления Аn Вы можете придумать? Попробуйте.
САМОСТОЯТЕЛЬНАЯ РАБОТА
Перевести арабские числа в римские (например, XCIX<=>99)
Имеется уравнение (оно называется разностным):
A(0)=1,
A(n)=A(n div 2) +A(n div 3)
Вычислить решения разностного уравнения от 1 до указанного номера.
Ханойская башня: необходимо перенести n дисков разного диаметра со стержня а на стержень с, используя стержень b как вспомогательный. Каждый меньший диск располагается на большем по диаметру диске. Взаиморасположение дисков после перемещения должно сохраниться. Разрешается переносить только один из верхних дисков какого-то стержня. Больший диск класть на меньший нельзя.
Для одного кольца сразу же перекладываем диск с a на c и сообщаем об этом.
Для двух дисков выполняем следующий перенос: ( указывается номер диска, и за двоеточием имя исходного диска “–“ имя конечного диска)
1: a-b 2: a-c 3: b-c (***)
А если у меня три кольца? Рассуждаем: переломное действие –переложить нижнее кольцо на пустой стержень. Для этого предварительно куда-то надо убрать два верхних кольца. А этот алгоритм уже освоен (***).
Пример работы программы:
vvedite n=3
a-c a-b c-b a-c b-a b-c a-c
vvedite n=4
a-b a-c b-c a-b c-a c-b a-b a-c b-c b-a c-a b-c a-b a-c b-c
Можно изменить порядок стержней и получить несколько другую программу:
Пример работы программы:
vvedite n=4
a-c a-b c-b a-c b-a b-c a-c a-b c-b c-a b-a c-b a-c a-b c-b
Задание: попробовать решить эту задачу нерекурсивно.
Сколько перекладываний понадобится для переноса 5 колец? 6 колец?
КОНТРОЛЬНЫЕ ВОПРОСЫ:
Какой процесс называют рекурсией?
Какие «правила безопасности» следует соблюдать при программировании рекурсивных функций?
Что называют глубиной рекурсии?
Что такое прямая рекурсия?
Для каких целей создают рекурсивные алгоритмы?
ЛАБОРАТОРНАЯ РАБОТА
Тема: АЛГОРИТМЫ КОМБИНАТОРИКИ
ЦЕЛЬ: Учащиеся должны освоить алгоритм генерации перестановок элементов и иметь понятие о сочетаниях и размещениях.
ПО: PASCAL
ТЕОРИЯ:
Область математики, в которой изучаются вопросы о том, сколько различных комбинаций, подчиненных тем или иным условиям, можно составить из заданных объектов, называется комбинаторикой.
Основными величинами комбинаторики являются сочетания, размещения и перестановки.
Комбинации из n различных элементов, взятых в определенном порядке, называются перестановками из n элементов.
П р и м е р. Перестановки из элементов1, 2, 3 будут:
123, 132, 213, 231, 312, 321
Количество перестановок из n элементов будет равно Pn =n!=1*2*3*…*n. При этом 0!=1.
Комбинации, отличающиеся друг от друга по крайней мере одним элементом, каждое из которых содержит m элементов, взятых из n различных элементов, называются сочетаниями из n элементов по m. Порядок следования элементов не учитывается.
П р и м е р. Все сочетания из элементов a, b, c, по два: ab, ac, bc.
Количество
сочетаний из k
по n
элементов равно
Комбинации, отличающиеся друг от друга составом элементов или их порядком, каждое из которых содержит m элементов, взятых из n различных элементов, называются размещениями из n элементов по m.
П р и м е р. Все размещения из элементов a, b, c по два: ab, ba, ac, ca, bc, cb.
Количество
размещений из k
по n
элементов равно
Пример 1. В футбольной группе участвуют 17 команд. Сколькими вариантами могут быть распределены золотые, серебряные и бронзовые медали в группе?
Решение: k=3, n=17. По формуле размещений Ank=n*(n-1)*…*(n-k+1)= 17*(17-1)*(17-2)= получаем 17*16*15=4080 вариантов распределения наград между командами.
Пример 2. Сколько анаграмм можно получить из слова "март"?
Решение. Поскольку в слове "март" у нас 4 буквы, то общее количество перестановок букв будет равно Pn=n!, т.е. 1*2*3*4=24 анаграммы.
Пример 3. Cколькими способами можно расставить на шахматной доске (64 клетки) 8 ладей?
Решение.
По формуле сочетаний
получаем
вариантов.
ПОСЛЕДОВАТЕЛЬНОСТЬ ВЫПОЛНЕНИЯ ЗАДАНИЯ:
1. Изучить необходимые сведения (см. выше).
2. Изучить задания. По каждому– разработать и ввести программу в память ЭВМ.
3. Выполнить программы.
6. Оформить отчет, защитить и сдать его преподавателю.
ЗАДАНИЯ
Сколько существует пятизначных чисел, состоящих из цифр 1, 2, 3, 4, 5, причем цифры не повторяются? Получите этот ответ с помощью программы.
Сколькими способами можно рассадить 24 ученика в классе, имеющем 28 свободных мест. Получите этот ответ с помощью программы.
Студентам требуется сдать 3 экзамена на протяжении 8 дней. Сколькими способами это можно сделать? Вычислите ответ с помощью компьютера.
Дана программа генерации перестановок из n элементов (n<=14, большее n не имеет практического смысла, хотя на экране помещается и n<=19):
-
Паскаль
Комментарии
var a,e: array[0..20] of integer;
s,n,i, j,f:integer;
begin
write('Vedite n<=14');
readln(n);
for i:=0 to n do a[i]:=i;
repeat
for i:=1 to n do write(a[i]:4);
writeln;
j:=n;
while a[j-1]>a[j] do j:=j-1;
f:=n;
while a[j-1]>a[f] do f:=f-1;
s:=a[j-1];
a[j-1]:=a[f];
a[f]:=s;
for i:=j to n do
e[i]:=a[n-(i-j)];
for i:=j to n do
a[i]:=e[i]
until a[0]<>0
end.
основной и вспомогательный массивы;
n- количество элементов в перестановке;
s–вспомогательная переменная;
I, j,f– управляющие переменные циклов;
[Ввод количества элементов n<=14]
[ Получение начальной комбинации 1 2 3 …n]
[Вывод очередной перестановки]
[Элемент с меньшим номером сравнивается с элементом с большим номером до тех пор, пока не нарушится упорядоченность, т.е. элемент слева не станет меньше элемента справа]
[Опять просматриваются элементы перестановки, пока не будет найден элемент, больший найденного в предыдущем цикле]
[Меняем
местами
два найденных элемента]
[Производится сортировка элементов, стоящих справа от найденного в порядке неубывания]
[в массиве а формируем новую перестановку]
[действия повторяются до тех пор,
пока 0-ой элемент массива не станет отличным от 0]
Введите в программу дополнительную переменную, которая бы считала число сгенерированных перестановок
САМОСТОЯТЕЛЬНАЯ РАБОТА: Задача о рюкзаке, которая формулируется так: Дан упорядоченный по неубыванию массив A целых положительных чисел и некоторое S. Необходимо найти все подпоследовательности массива A, сумма элементов которых равна в точности S.
А) Найти количество найденных последовательностей.
КОНТРОЛЬНЫЕ ВОПРОСЫ:
В каких случаях применяется перебор вариантов?
Когда он будет эффективнее?
Что является условием окончания перебора в программе генерации перестановок?
Что такое сочетания? Как подсчитать количество сочетаний?
Что такое размещения? Как подсчитать количество размещений?
Оценка–10, если выполнены все задания и есть развернутые ответы на вопросы, иначе – в соответствии с количеством выполненных заданий и есть ответы на вопросы.
