Задача 56.56. Два відрізки задано координатами своїх кінців. Визначити, чи перетинаються дані відрізки.
Розв’язання: Згадайте те, про що ми говорили раніше: очевидне не завжди найкраще! А це значить, що нам не потрібно шукати точку перетину відрізків, ми поступимо іншим чином. Будемо розглядати точки кінців одного відрізку відносно іншого відрізку. З геометрії відомо, що два відрізки перетинаються тоді і тільки тоді, коли кінці одного відрізку лежать в різних півплощинах відносно прямої, що проходить через інший відрізок. Причому потрібно розглядати обидва відрізка. Той факт, що дві точки лежать відносно прямої в різних півплощинах можна записати з використанням рівняння прямої таким чином:
Для точок С і D відносно прямої АВ:
((Xc-Xa)(Xb-Xa) - (Yc-Ya)(Yb-Ya))Ч((Xd-Xa)(Xb-Xa) - (Yd-Ya)(Yb-Ya))<0
Для точок A і B відносно прямої CD:
((Xa-Xc)(Xd-Xc) - (Ya-Yc)(Yd-Yc))Ч((Xb-Xc)(Xd-Xc) - (Yb-Yc)(Yd-Yb))<0
Щоб передбачити випадок, коли обидва відрізки лежать на одній прямій, або випадок, коли один відрізок одним своїм кінцем лежить на іншому відрізку, в сформульовані умови необхідно ще добавити перевірку на рівність нулю (див. попередню задачу). В завершеному вигляді маємо таку програму:
program line2;
var x1,x2,x3,x4,y1,y2,y3,y4 : integer;
begin
writeln('Координати точки А:');
write('Ха = ');readln(x1);
write('Ya = ');readln(y1);
writeln('Координати точки B:');
write('Хb = ');readln(x2);
write('Yb = ');readln(y2);
writeln('Координати точки C:');
write('Хc = ');readln(x3);
write('Yc = ');readln(y3);
writeln('Координати точки D:');
write('Хd = ');readln(x4);
write('Yd = ');readln(y4);
if (((x3-x1)*(x2-x1)-(y3-y1)*(y2-y1))*((x4-x1)*(x2-x1)-(y4-y1)*(y2-y1))<=0) and
(((x1-x3)*(x4-x3)-(y1-y3)*(y4-y3))*((x2-x3)*(x4-x3)-(y2-y3)*(y4-y3))<=0)
then writeln('Перетинаються.')
else writeln('Не перетинаються');
readln
end.
Інструкція Case
До цього часу ми розглядали нескладні випадки розгалужень. Перед тим як перейти до подальшого матеріалу, розглянемо ще одну задачу.
Задача 57.57. В залежності від отриманої учнем оцінки вивести на екран відповідне повідомлення.
Розв’язання: Використовуючи команду розгалуження не складає труднощів написати наступну програму:
program ocenka1;
var o : integer;
begin
write(‘Введiть отриману оцiнку: ’);
readln(o);
if o = 5 then writeln(‘Молодець! Вiзьмеш дома цукерку.’)
else if o = 4 then writeln(‘Непогано! Але без цукерок!’)
else if o = 3 then writeln(‘Мiг би й краще!’)
else if o = 2 then writeln(‘Мабуть ти забув про школу.’)
else writeln(‘Пробач, але такої оцiнки не ставлять.’);
readln
end.
Зверніть увагу на кількість розгалужень. Тут, хоч їх і не так вже багато, можна й заплутатись яке else до якого if відноситься. Саме для таких випадків і передбачено у мові Паскаль конструкцію вибору. Конструкція вибору описується так:
в залежності від значення змінної зробити вибір, а саме:
при значенні1 – вивести повідомлення1;
при значенні2 – вивести повідомлення2;
...
при значенніn – вивести повідомленняn.
У шкільній алгоритмічній мові також існує конструкція вибору, але ми її тут наводити не будемо, а лише опишемо конструкцію вибору на мові Паскаль, причому дамо смисловий переклад організації конструкції:
...
case o of
{ вибір від значення змінної о }
<01>: <дія1>; { при одному значенні – одна дія }
<02>: <дія2>; { при другому – друга дія }
<03>: <дія3>; { при третьому значенні – третя дія }
<04>: <дія4>; { при четвертому значенні – четверта дія }
end;
{ кінець вибору }
...
Якщо після якогось значення змінної потрібно виконувати не одну дію, а декілька, то всі оператори, що відносяться до даного випадку беруться в операторні дужки begin ... end. Крім того, конструкція case передбачає варіант виконання дій у тому випадку, коли змінна не набула жодного з вказаних у операторі вибору значень – цьому призначено, як і при організації умовного оператора команду else. Знову ж таки, перед гілкою else крапку з комою ставити забороняється.
Ви вже, напевне, самі звернули увагу, що для команди case обов’язково в кінці ставиться end, тобто в нас з’явилась ще одна “нерозлучна солодка парочка”.
Отже спробуємо розв’язати останню задачу при допомозі команди вибору.
program ocenka2;
var o : integer;
begin
write(‘Введiть отриману оцiнку: ’);
readln(o);
case o of
5: writeln(‘Молодець! Вiзьмеш дома цукерку.’);
4: writeln(‘Непогано! Але без цукерок!’);
3: writeln(‘Мiг би й краще!’);
2: writeln(‘Мабуть ти забув про школу.’)
else writeln(‘Пробач, але такої оцiнки не ставлять.’);
end; { case }
readln
end.
Зверніть увагу наскільки в порівнянні з попереднім варіантом більш зрозумілою стала наша програма.
Цікавою і цінною особливістю організації команди вибору є те, що можна організовувати однакові дії для цілого діапазону значень. Продемонструємо це на конкретному прикладі.