- •Використання рекурсивних алгоритмів. Розв’язування задач.
- •Хід уроку
- •1. Перевірка домашнього завдання.
- •2. Актуалізація опорних знань.
- •Var n: Integer;
- •Що виведе на екран програма ?
- •Var n: Integer;
- •3. Мотивація.
- •4. Вивчення нового матеріалу.
- •Var X, y, z : char;
- •Var і, к, j : integer;
- •Var n, і : Integer;
- •Var м, n : Integer;
- •5. Створення та реалізація програми
- •6. Підсумки уроку.
- •Var s, а, в, d: Integer;
- •Var s, a, n, d: Integer;
- •7. Домашнє завдання.
- •Var s : String;
- •Var s : String;
- •Var s : String;
- •8. Підготуватися до тематичного оцінювання з теми «Функції та процедури».
Var n, і : Integer;
Function S (і : Integer) : integer;
Begin
If i=N-1 Then S:=1
Else If i=N-2 Then S:=2
Else if і =N—3 Then S:=4
Else S:=S(i+1)+S(i+2)+S(i+3);
End;
Begi n
і: =0; {Ми на 0-й сходинці, тобто перед сходами)
Write ('n=>');
ReadLn (N);
WriteLn (S(i));
End.
Приклад 19.
Кількість розбиттів(склад) числа. Ціле додатне число можна зобразити сумою його частин, що називається розбиттям. Наприклад, число 4 можна зобразити так:
4; 3+1; 2+1 + 1; 2+2; 1 + 1 + 1 + 1.
Р(n) — кількість розбиттів, Р(4)=5.
Для заданого числа п знайти всі його розбиття та кількість розбиттів Р(п).
Розв'язок.
Ця задача вважається класичною. Для її розв'язання слід придумати спосіб визначення функції Р(n) через такі значення або інші функції, які обчислити легше.
Введемо іншу функцію Q(m,n), яку визначимо як кількість розбиттів цілого m з доданками, що не більші від n. За допомогою рекурсивних міркувань можна записати такі співвідношення:
а) Q(m,1)= 1; це означає, що існує лише одне розбиття цілого числа m, у якому найбільший доданок дорівнює одиниці, а саме
m= 1 + 1+...+ 1;
б) Q(1,n)=1; очевидно, існує лише одне розбиття цілого числа 1 незалежно від величини n найбільшого доданка;
в) Q(m,n)= Q(m,m), якщо m<n; зрозуміло, що ніяке розбиття m не може мати доданка n, більшого від m;
г) Q(m,m)=1+ Q(m,m-1); існує лише одне розбиття m з доданком, рівним m всі інші розбиття m мають найбільший доданок n<=m-1;
Д) Q(m,n)= Q(m,n-1)+ Q(m-n,n); це означає, що будь-яке розбиття m з найбільшим доданком, меншим або рівним n, або не містить n як доданок — в цьому випадку дане розбиття також входить в число Q(m,n-1), або містить n — при цьому решту доданків утворюють розбиття числа m-n.
Рівняння а)—д) рекурсивно визначають функцію Q(m,n). Вони визначають Р(m), Р(m)= Q(m,m).
Друкувати ж самі розбиття числа можна в процесі обчислення Р(n) в ті моменти, коли знайдено чергове розбиття. Для цього можна завести глобальний масив, у якому пам’ятати всі знайдені на поточний момент частини заданого числа,
Var м, n : Integer;
Function Q (M, N : integer): integer;
Begin
if N=1 Then Q:=1
Else if M=1 Then Q:=l
Else if M<N Then Q:=Q (M, M)
Else if m=n Then Q:=1+Q (M, M-1)
Else Q:= Q (M, N-l) + Q (M-N, N);
End;
Begin
ReadLn (M);
WriteLn (Q (M, M));
End.
5. Створення та реалізація програми
Задача.
Задано деякий одновимірний масив дійсних чисел R[1 .. М], де 1 <М< 100. Необхідно знайти суму від'ємних елементів масиву.
Функцію для обчислення такої суми можна визначити рекурсивно:
де Е - це індекс елемента масиву R, починаючи з якого і до елемента з номером М обчислюється потрібна сума. Щоб знайти суму від'ємних значень усього масиву, необхідно обчислити SVID(R,1). Ідея рекурсивного визначення: шукана сума - це є сума чергового елементу, якщо він від'ємний, та решти від'ємних, де решта від'ємних у свою чергу визначається так само.
Наступний рекурсивний алгоритм реалізує необхідні обчислення:
Type А=Аггау [1..100] of Real;
Var R: A;
і, E, M: integer;
S: Real;
Function Svid (R: a; m, E: Integer): Real;
Begin
If e=m Then If R[m]<0 Then Svid:=R[M]
Else Svid:=0
Else if r[e]<0 Then Svid:=R[E]+Svid (r,m,e+1)
Else Svid:=Svid (R,M,E+1);
End;
Begin
write ('M=>'); ReadLn (M);
For i:=l To м Do ReadLn (R [i]);
S:=Svid (R, м, 1);
WriteLn (S : 6 : 2)
End.
Нехай X : Array[1..40] of Real. Які обчислення будуть виконуватися після таких звертань до функції Svi d:
а) S:=Svid (X,20,1);
б) S:=Svid (х,40,21);
в) S:=Svid (X, 30,10);
г) S:=Svid (Х,35,15)+ Svid (X,14,1)+ Svid (X,40,36)?
Задано деякий одновимірний масив дійсних чисел К[тіп..тах]. Необхідно знайти від'ємний елемент цього масиву з найменшим номером (індексом), тобто, найперший за порядком. Якщо від'ємних значень немає взагалі, то результатом пошуку має бути число 0.
Визначимо відповідну рекурсивну функцію:
Поясніть наведене визначення рекурсивної функції, її ідею.
Складемо програму для обчислення за даною рекурсивною функцією:
Туре А=Аггау [1..100]of Real;
var К:А;
і, N : Integer; Min, Max : Real;
S : integer;
Function Pvid (K : A; N : integer) : Real;
Begin
if N>Max Then Pvid:=0
Else If (N<=Max) And (K[N]>=0)
Then Pvid:=Pvid(K, N+l)
Else Pvid:=K[N];
End;
Begin
write ('Min, Max=>');
ReadLn (Min, Max);
For і:=міп To мах Do ReadLn (K[I]);
S:=Pvid (K, 1); writeLn (S)
End.
Проаналізуйте роботу програми на прикладах.
Нехай К= (1,2,-3,4,-5,6,-7,8,-9,10). Якого значення набуде величина S після виклику функції Pvid з такими параметрами:
а) S:=Pvid (К, 1); min=1, max=10;
б) S:=Pvid (К, 1); min=1, max=3;
в) S:=Pvid (К, 6); min=5, max=10;
б) S:=Pvid (К, 1); min=1, max=4?
