Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основи програмування Паскаль.docx
Скачиваний:
51
Добавлен:
12.05.2015
Размер:
511.7 Кб
Скачать

13. Розв'язок навчальних завдань на цикли

Використовуючи отримані навички роботи з типовими алгоритмами, розглянемо кілька навчальних завдань різних типів.

На практиці нерідко зустрічаються завдання, для яких число кроків циклу заздалегідь невідомо й не може бути обчислене. Як правило, у цьому випадку розрахунковий цикл працює до виконання деякої умови, що визначає досягнення необхідного результату. Приведемо приклад подібного завдання.

Пр.Задана функція і її розкладання в ряд:

n=0,1,2,… (тут n! позначає факторіал числа n, рівний 1*2*3*….*n; при цьому 0!=1). Знайти число елементів ряду k, необхідне для досягнення заданої точності ε.

Це – типове завдання на ряди. З ростом n доданки стають усе менше, так само як і модуль різниці між двома сусідніми доданками. Тому під досягненням заданої точності будемо розуміти виконання умовиде Sn, Sn-1 – суми ряду, обчислені на поточному й попередньому кроках циклу, ε задається малим числом, від 10-6 і нижче. Для обчислення x2nуведемо зміннуxn, яку на кожному кроці циклу будемо домножать на x2, аналогічно, для обчислення поточного значення факторіала використовуємо зміннуnf. Інший підхід зажадав би великої кількості повторних обчислень на кожному кроці циклу, плюс був би чреватий більшими втратами точності. Для обчислення (-1)nбуло б дивно використовувати формулу ax=exln a– цілком достатньо завести целочисленную зміннуznak, рівну1, яка на кожному кроці циклу буде міняти своє значення на протилежне операторомznak:=-znak;. Крім того, тому що необхідне число кроків заздалегідь невідомо, використовуємо для всіх основних змінних більш точний типdoubleзамістьreal.

Реалізуємо все сказане в наступній програмі:

{$N+} {Директива режиму сумісності з 80287 - для використання double}

var x,sn,sn1,xn,nf,eps:double;

k,n:longint;

znak:integer;

begin

writeln ('Уведіть значення x для розкладання в ряд:');

read (x);

writeln ('Уведіть необхідну точність:');

read (eps);

sn1:=0;

sn:=0;

k:=0;

n:=0;

xn:=1;

nf:=1;

znak:=1;

repeat

sn1:=sn; {Поточна сума стала попередньою для наступного кроку}

sn:=sn+znak*xn/nf; {Виконуємо крок циклу}

{Міняємо змінні для наступного кроку:}

znak:=-znak;

xn:=xn*sqr(x);

nf:=nf*(n+1)*(n+2);

n:=n+2;

k:=k+1;

until abs(sn1-sn)<eps;

writeln ('Точне значення функції=',cos(x):20:16);

writeln ('Попередня сума=',sn1:20:16);

writeln ('Поточна сума=',sn:20:16);

writeln ('Число кроків=',k);

reset (input); readln;

end.

До глави "Графіка" ще далеко, але навіть у звичайному текстовому режимі роботи можна наочно проілюструвати результати своїх розрахунків. Розглянемо як приклад завдання:

Пр.Сформувати на екрані зображення функції

f(x)= cos(x)+ln(x)

на інтервалі [1,5] із кроком 0.2.

Програма з докладними коментарями приводиться нижче:

var x,y, { Значення аргументу й функції }

a,b, { Інтервал }

ymin,ymax:real; { Мінімальне й максимальне Y }

cy, { Позиція стовпця на екрані }

i:integer; { Лічильник для циклу for }

begin

a:=1;

b:=5;

{ Перший цикл потрібний, щоб визначити мінімальне й максимальне

значення функції на заданому інтервалі }

x:=a; { Починаємо з лівої границі }

ymin:=1e20; ymax:=1e-20; { Мінімуму привласнюємо велике число,

максимуму - маленьке }

while x<=b do begin { Поки x не перевищило правої границі }

y:=cos(x)+ln(x); { уважаємо чергове значення функції }

if y<ymin then ymin:=y { Шукаємо мінімум }

else if y>ymax then ymax:=y; { Шукаємо максимум }

x:=x+0.2; { Переходимо до наступного x }

end; { Кінець першого циклу }

{ У другому циклі обробки можна виводити на екран значення функції }

x:=a;

while x<=b do begin { Поки x не перевищило правої границі }

y:=cos(x)+ln(x); { уважаємо чергове значення функції }

cy:=Round ( 8+(y-ymin)*(70/(ymax-ymin)) );

{ Щоб перерахувати y із границь [ymin,ymax] у границі [8,78] (стовпці

екрана, у які виводимо графік), використовуємо формулу

78 - 8

cy= 8 + (y-ymin) * -----------

ymax - ymin

Тепер у змінній cy - потрібний нам стовпець екрана }

writeln; { Переходимо до нового рядка на екрані }

write (x:7:3,' '); { Виводимо значення x і пробіл }

for i:=8 to cy do write ('*'); { Малюємо зірочками значення y }

x:=x+0.2; { Переходимо до наступного x }

end; { Кінець другого циклу }

end.

Пр.Перевірити, чи є введене позитивне ціле число N простим.

Очевидно, що просте число ділиться без залишку тільки на одиницю й саме на себе. У циклі послідовно перевіримо залишки від розподілу N на числа 2,3,…,N-1. Якщо знайдений хоча б один залишок, дорівнює нулю, число не є простим і подальші перевірки безглузді. Зверніть увагу на використання логічної змінної-прапора sу цій програмі.

var n,i:longint;

s:boolean;

begin

write ('N=');

readln (n);

s:=true;

for i:=2 to n-1 do

if n mod i = 0 then begin

s:=false;

break;

end;

if s=true then writeln ('простої')

else writeln ('НЕ простої');

end.