Тема уроку: "Алгоритми і програми роботи з лінійними таблицями."

На початку уроку бажано зробити опитування (можна в письмовому або усному вигляді) за матеріалом попереднього уроку та повторити тему "Команда повторення", особливо різновид циклу - цикл з параметром.
Далі рекомендується розглянути методи розв'язку деяких типових задач по обробці лінійних таблиць.
Зверніть увагу на те, що дуже велика кількість задач по обробці масивів потребує виконання однотипних дій з усіма її елементами, тому зручно в цих випадках використовувати цикл з параметром для організації повторення.
Задача №300.
Умова: Барон Мюнхаузен, вийшовши на екологічно чисте полювання, зарядив свою рушницю кісточками вишень. Після того як він вдало влучив поміж роги оленям, в яких влучило відповідно k1, k2, …, kn кісточок, у них на головах виросли чудові молоді вишеньки. Скільки саджанців зміг подарувати барон Мюнхаузен садівникам-дослідникам?
Для розв'язування цієї задачі пропонується використати масив для зберігання кількості кісточок, що влучили поміж роги оленям. Так як кількість кісточок являється цілим числом, масив повинен мати розмірність N елементів цілого типу. Для спрощення відлагодження програми доречно використовувати автоматичне заповнення масиву за допомогою генератора випадкових чисел, а з метою перевірки правильності роботи програми після заповнення масив виводиться на екран.
Програма, що реалізує розв'язок цієї задачі, має наступний вигляд:

Program Example_300; 
Uses crt; 
Var N:word; {N - кількість оленів, тобто  
елементів масиву, у яких влучив  
Мюнхаузен} 
K:array[1..100] of longint; {K - зарезервований  
масив для зберігання кількості  
кісточок, що влучили в оленів} 
i,Sum:longint; {i - змінна циклу, Sum - загальна  
кількість кісточок, що влучили в  
оленів} 
Begin 
Randomize; {Ця процедура запускається з метою  
зробити числа генератора  
випадкових чисел ще більш  
"випадковими"} 
Clrscr; 
Sum:=0; {На початку роботи програми Мюнхаузен  
ще ні в кого не влучив} 
Write ('Введіть кількість оленів, в яких влучив  
Мюнхаузен (<=100): '); 
Readln(N); 
For i:=1 to N do 
Begin 
K[i]:=random(50)+20; {Заповнення масиву  
випадковими числами в  
діапазоні від 20 до 70} 
Write(K[i]:5); {Виведення масиву на екран  
для контролю правильності  
роботи програми} 
Sum:=Sum+K[i]; 
End; 
Writeln; {Переведення курсору на новий  
рядок} 
Writeln ('Кількість нових саджанців ',Sum); 
Readkey; {Затримка зображення на екрані} 
End. 
Задача №302.
Умова: Середню групу дитячого садочка вивели на прогулянку. Скільки дівчаток і скільки хлопчиків видна з-за паркану, якщо зріст хлопчиків задається у сантиметрах від'ємними числами, а дівчаток - додатними у вигляді цілих значень a1, a2, …, an? Крім того, у всіх дівчаток на голівках зав'язані бантики заввишки 10 см, а висота паркану H см.
Задача майже нічим не відрізняється від попередньої, тільки при заповненні в масиві повинні з'являтись і додатні, і від'ємні числа. Для пошуку в масиві елементів з заданою властивістю (в даному випадку чисел, що по модулю більші ніж задане) використовується вже відома команда розгалуження.
Program Example_302; 
Uses crt; 
Var N,H:word; {N - кількість дітей в дитсадочку,  
Н - висота паркану} 
А:array[1..100] of longint; {А - зарезервований  
масив для зберігання зростів  
дітей} 
i,Count_girl,Count_boy:longint;  
{i - змінна циклу, Count_girl -  
кількість дівчаток, Count_boy -  
кількість хлопців} 
Begin 
Randomize;  
Clrscr; 
Count_girl:=0; 
Count_boy:=0; 
Write ('Введіть висоту паркану: '); 
Readln(H); 
Write ('Введіть кількість дітей в дитсадочку: '); 
Readln(N); 
For i:=1 to N do 
Begin 
A[i]:=random(300)-150; {Заповнення масиву  
випадковими числами в  
діапазоні від -150 до +150} 
Write(А[i]:5); {Виведення масиву на екран  
для контролю правильності  
роботи програми} 
if (A[I]<0) and (abs(A[I])>H) 
then Count_Boy:=Count_Boy+1; 
if (A[I]>0) and (A[I]+10>H) 
then Count_Girl:=Count_Girl+1; 
End; 
Write ('Кількість хлопчиків, що видна з-за паркану '); 
Writeln (Count_Boy); 
Write ('Кількість дівчаток, що видна з-за паркану ,); 
writelnCount_girl); 
Readkey; {Затримка зображення на екрані} 
End. 

Задача №309.
Умова: Дано натуральне число А. Складіть програму, що представляє його у вигляді многочлена. Наприклад,
123 ==>1 * 10^2 + 2 * 10^1 + 3*10^0.
Ця задача фактично зводиться до пошуку окремих цифр числа. Так як ми не знаємо на початку роботи, скільки цифр має число, для їх зберігання можна використати масив цілих чисел, причому розмірність цього масиву можна задати не більше 10 елементів, тому що навіть найбільше ціле число типу longint має в своєму складі не більше 10 цифр.
Щоб вивести на екран отриманий многочлен, ми спочатку знаходимо кількість цифр в числі, а потім організовуємо цикл від найстаршої значущої (ненульової) цифри числа до молодшої з виведенням на екран самої цифри, помноженої на 10 в степені номер розряду -1 (тобто i-1).
Програма, що реалізує описаний алгоритм, має наступний вигляд:

Program Example_309; 
Uses crt; 
Var N,i,Count:longint; {N - задане ціле число, i -  
змінна циклу, Count - кількість  
цифр в числі} 
Cifra:array [1..10] of byte; {Cifra - масив для  
зберігання цифр числа} 
Begin 
Clrscr; 
Count:=0; 
Write ('Введіть ціле число: '); 
Readln (N); 
While N>0 do 
Begin 
Cifra[i]:=N mod 10; 
N:=N div 10; 
Count:=Count+1; 
End; 
Write('N = '); 
For i:=N downto 1 do 
Begin 
Write(Cifra[i],'*10^',i-1); 
If i>1 
Then write(' + '); {Якщо доданок не останній,  
то до нього дописується  
знак "+"} 
End; 
Readkey; {Затримка зображення на екрані} 
End. 
 

Задача №312.
Умова: Дано дійсні числа a1951, a1952, …, a2000 - кількість опадів (в мм), що випали у місті за останні 50 років минулого століття. Обчислити середню кількість опадів за цей період і щорічне відхилення від середнього значення.

В цій задачі прийдеться організовувати прохід по масиву двічі, так як першим проходом ми знайдемо тільки суму всіх опадів, що випали за останні 50 років, а потім поділивши отриманий результат на 50 знайдемо середню кількість опадів за вказаний період. Другим же проходом ми можемо вже визначити щорічне відхилення від середнього значення, причому для того, щоб не втратити вхідні дані, зарезервуємо в програмі ще один масив на 50 дійсних чисел для зберігання цих результатів.

Program Example_312; 
Uses crt; 
Var N,i:longint; {N - кількість елементів масиву, i  
- змінна циклу} 
A:array[1951..2000] of real; {A - масив для  
зберігання кількості  
опадів у відповідному році} 
B:array[1951..2000] of real; {B - масив для  
зберігання відхилення від  
середнього значення} 
Begin 
Randomize;  
Clrscr; 
Sum:=0; 
For i:=1951 to 2000 do 
Begin 
A[i]:=random(500)/7; {Заповнення масиву  
випадковими дійсними числами} 
Write(A[i]:8:2); {Виведення масиву на екран  
для контролю правильності  
роботи програми} 
Sum:=Sum+K[i]; 
End; 
Sum:=Sum/50; {Знаходження середньої кількості  
опадів за рік} 
Writeln; 
Writeln ('Щорічні відхилення від середньої кількості опадів за період 1951 - 2000 р.р.'); 
For i:=1951 to 2000 do 
Begin 
B[i]:=Sum - A[i]; {Знаходження щорічного  
відхилення} 
Write(B[i]:8:2); {Виведення результатів на  
екран} 
End; 
Readkey; {Затримка зображення на екрані} 
End. 
 

Задача №315 (1).
Умова: Дано натуральне число n та цілі числа a1, a2, … an і b1, b2, … , bn. Визначити значення c1, c2, … , cn, якщо ci = ai + bi.

Program Example_315_1; 
Uses crt; 
Const N=100; 
Type 
Masiv = array[1..N] of integer; 
Var A,B,C:Masiv; {A,B - масиви для зберігання  
вхідних даних, С - вихідний  
масив} 
i:byte; {і - змінна циклу} 
Begin 
Randomize;  
Clrscr; 
For i:=1 to N do 
Begin 
A[i]:=random(200); {Заповнення масиву  
випадковими цілими числами} 
Write(A[i]:4); {Виведення масиву на екран  
для контролю правильності  
роботи програми} 
End; 
Writeln;  
For i:=1 to N do 
Begin 
B[i]:=random(200); 
Write(B[i]:4);  
End; 
Writeln;  
For i:=1 to N-1 do 
Begin 
C[i]:=a[i]+b[i]; 
write(c[i]:4); 
End; 
Readkey; {Затримка зображення на екрані} 
End. 
 

Задача №318 (1).
Умова: Дано дійсні числа a1, a2, …, a30, b1, b2, …, b30. Обчислити
(a1 + b30)(a2 + b29)…(a30 + b1).
Очевидно, що для обчислення даного виразу необхідно організувати цикл по тридцяти елементах масивів A та B, в якому індекси обох масивів будуть змінювати в протилежних напрямках. Для цього існує такий штучний прийом: зміну одного з індексів ми організовуємо за допомогою циклу з параметром, а зміну другого - за допомогою формули. Вочевидь, що в даному випадку ця формула має такий вигляд: j:=31 - і, де i та j - індекси відповідно масивів А та В. Програма, що реалізує запропонований алгоритм, маж наступний вигляд:

Program Example_318_1; 
Uses crt; 
Var A,B: array[1..30] of real; 
{A,B - масиви для зберігання вхідних даних} 
i:byte; {і - змінна циклу} 
Rez:real; {Rez - результат обчислень} 
Begin 
Randomize;  
Clrscr; 
Writeln ('Масив А:'); 
For i:=1 to 30 do 
Begin 
A[i]:=random(200)/7-random*15; 
Write(A[i]:8:2);  
End; 
Writeln ('Масив В:'); 
For i:=1 to 30 do 
Begin 
B[i]:=random*200-random*100; 
Write(B[i]:8:2);  
End; 
Writeln;  
Rez:=1;  
{Початкове значення дорівнює 1, тому що результат  
являється накопиченням добутку} 
For i:=1 to 30 do 
Begin 
Rez:=Rez*(A[i]+B[31-i]); 
End; 
Writeln ('Результат обчислень = ',Rez:8:2); 
Readkey; {Затримка зображення на екрані} 
End. 
 

Задача №318 (4).
Умова: Дано дійсні числа a1, a2, …, a30, b1, b2, …, b30. Обчислити

Очевидно, що для обчислення результату цієї задачі спочатку необхідно знайти чисельник та знаменник дробу. Причому зверніть увагу на те, що кількість доданків і в одному, і в другому випадках дорівнює 15, тільки в чисельнику вибираються елементи масивів з непарними індексами, а в знаменнику - з парними. Щоб організувати зміну індексів за заданим законом, можна скористатися таким штучним прийомом: якщо в циклі з параметром індекс i змінюється від 1 до n, то для отримання непарних чисел з проміжку [1..2n] використовується така формула: 2*i - 1.
Запропонуйте дітям подумати, яка формула дозволить отримати парні числа.
Використовуючи ці співвідношення, програма для розв'язку цієї задачі має наступний вигляд:

Program Example_318_4; 
Uses crt; 
Var A,B:array[1..30] of real; 
{A,B - масиви для зберігання вхідних даних} 
i:byte; {і - змінна циклу} 
R1,R2:real; {R1 - чисельник дробу, R2 -  
знаменник дробу} 
Rez:real; {Rez - результат обчислень} 
Begin 
Randomize;  
Clrscr; 
Writeln ('Масив А:'); 
For i:=1 to 30 do 
Begin 
A[i]:=random(200)/7-random*15; 
Write(A[i]:8:2);  
End; 
Writeln ('Масив В:'); 
For i:=1 to 30 do 
Begin 
B[i]:=random*200-random*100; 
Write(B[i]:8:2);  
End; 
Writeln;  
R1:=0;  
R2:=0; 
{Початкове значення дорівнює 0, тому що результат  
являється накопиченням суми} 
For i:=1 to 15 do 
Begin 
R1:=R1 + (A[2*i-1]+B[2*i-1]); 
R2:=R2 + (A[2*i]+B[2*i]); 
End; 
Rez:=R1/R2; 
Writeln ('Результат обчислень = ',Rez:8:2); 
Readkey; {Затримка зображення на екрані} 
End.