матеріали для
підтримки вивчення предмету

Алгоритмічна структура розгалуження

Для розв’язання усіх задач, які розглядалися вище, ми складали алгоритми, в яких всі дії виконувалися послідовно одна за одною. Такі алгоритми називаються лінійними. За допомогою лінійних алгоритмів можна розв’язувати, як правило, лише найпростіші задачі. Досить часто при розв’язуванні задач потрібно аналізувати умову, і в залежності від того, виконується вона або ні, виконувати різні дії. Алгоритмічна структура розгалуження – це структура, в якій, в залежності від поставленої умови, виконуються різні команди. В мові програмування C# існує три види алгоритмів розгалуження:

Команда розгалуження if – else

На рис. 6.1 зображено алгоритмічну структуру розгалуження за допомогою блок-схеми.

Програмування на C#
рис. 6.1

Мовою C# дана структура записується таким чином:

if (умова)
    {
      команда 1;
      команда 2;
      …;
    }
  else
    {
      команда 1;
      команда 2;
      …;
    }

В команді розгалуження if – else спочатку аналізується умова, якщо умова істинна (+) – виконуються дії 1, якщо ж умова хибна (–) – виконуються дії 2.

Зауваження 1. Блок else в даній структурі є не обов’язковим. Розгалуження без блоку else називають неповним (рис. 6.2).

Програмування на C#
рис. 6.2

В C# неповне розгалуження записується так:

if (умова)
    {
      команда 1;
      команда 2;
      …;
    }

Зауваження 2. Якщо у гілках істинності умови (+) або/i хибності умови (–) потрібно виконати лише одну команду, то фігурні дужки можна не ставити. Таким чином, алгоритм може бути записаний в скороченій формі:

if (умова) 
     команда 1; 
  else
     команда 2;

Операції порівняння

До складу умови можуть входити числа, змінні, математичні вирази, які поєднуються операціями порівняння. Розглянемо, як записуються операції порівняння в C#.

C# Операція порівняння
> Більше
< Менше
>= Більше або дорівнює
<= Менше або дорівнює
== Дорівнює
!= Не дорівнює
таблиця 8

Розв'язування задач з використанням розгалуження

Створіть рішення «Lesson_6» проект «Task_1». Відомо два різних числа. Визначити менше з них (рис. 6.3).

Програмування на C#
рис. 6.3

Програмний код для розв’язання поставленої задачі наступний:

private void button1_Click(object sender, EventArgs e)
        {
            int a = int.Parse(textBox1.Text);
            int b = int.Parse(textBox2.Text);
            int min;
            if (a < b)
                min = a;
            else min = b;
            label4.Text = min.ToString();
        }

У використаному розгалуженні в обох гілках виконується лише по одній команді, а отже, можна використати його скорочену форму запису (без фігурних дужок).

Розглянемо завдання №2 (рішення lesson_6, проект task_2).

Скласти програму для обчислення функції:

Програмування на C#

Дана програма повинна, в залежності від введеного аргументу, виводити обчислене значення функції або виводити повідомлення «Обчислити неможливо!». Інтерфейс програми зображено на рис. 6.4.

Програмування на C#
рис. 6.4

Програмний код наведено нижче:

private void button1_Click(object sender, EventArgs e)
    {
        double x = double.Parse(textBox1.Text);
        double y;
        if (x >= 10)
          {
            y = Math.Round(Math.Sqrt(x - 10),5);
            label2.Text = "y = " + y.ToString();
          }
        else
          label2.Text = "Обчислити неможливо!";
    }

Проаналізуємо записане розгалуження. У випадку виконання умови (введено значення з області визначення функції) потрібно виконати дві дії: обчислити значення функції та вивести його на екран, а отже, фігурні дужки є обов’язковими. В гілці невиконання умови лише одна дія – виведення на екран текстового повідомлення – фігурні дужки не є обов’язковими.

Логічні операції

Логічні умови виду x>5 або a<=0 називають простими умовами. Складені умови поєднують в собі декілька простих умов. Для поєднання декількох простих умов використовують логічні операції кон’юнкції та диз’юнкції:

C# Логічна операція Приклад запису
&& Логічне «І» - кон’юнкція. Логічний вираз буде істинним, якщо кожна з простих умов буде істинна. Хибним – якщо хоча б одна з простих умов є хибною. x>0 && x<100
|| Логічне «АБО» - диз’юнкція. Логічний вираз буде істинним, якщо хоча б одна з простих умов буде істинна. Хибним – якщо кожна з простих умов є хибна. a==b || b==c || a==c
таблиця 9

Завдання №3 (рішення lesson_6, проект task_3).

Скласти програму для обчислення функції:

Програмування на C#

Дана програма повинна, в залежності від введеного аргументу, виводити обчислене значення функції або виводити повідомлення «Обчислити неможливо!». Інтерфейс програми зображено на рис. 6.5).

Програмування на C#
рис. 6.5

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

private void button1_Click(object sender, EventArgs e)
    {
        double x = double.Parse(textBox1.Text);
        double y;
        if (x <= 5 && x!=1)
          {
            y = Math.Round(Math.Sqrt(5 - x) / (x - 1), 5);
            label2.Text = "y = " + y.ToString();
          }
        else
          label2.Text = "Обчислити неможливо!";
    }

Вкладеність операторів if – оператор else if

Програмування на C#
рис. 6.6

Розглянемо завдання №4 (рішення lesson_6, проект task_4). Відомо сторони трикутника. Скласти програму, яка визначає тип трикутника: “Рівносторонній”, “Рівнобедрений” або “Різносторонній” (рис. 6.6).

На відміну від попередніх завдань, в даному потрібно реалізувати розгалуження в три напрямки. Для таких випадків потрібно використовувати вкладеність операторів if – в середину одного оператора if “вкласти” інший.

private void button1_Click(object sender, EventArgs e)
    {
        int a = int.Parse(textBox1.Text);
        int b = int.Parse(textBox2.Text);
        int c = int.Parse(textBox3.Text);
        if (a == b && b == c)
           label4.Text = "Рівносторонній";
        else if (a == b || b == c || a == c)
                label4.Text = "Рівнобедрений";
             else label4.Text = "Різносторонній";
    }

Оператор вибору

В мові C# існує оператор вибору, який дозволяє реалізувати розгалуження обчислювального процесу в багато напрямків. В загальному оператор вибору має такий вигляд:

switch (змінна)
   {
      case значення1: 
         блок1;
         break;
      case значення2: 
         блок2; 
         break;
      ... 
      case значення N: 
         блокN; 
         break; 
      default: 
         блок;
         break;
   }
Програмування на C#
рис. 6.7

Для кращого розуміння даної структури розглянемо два завдання (рішення lesson_6, проект task_5, task_6).

Завдання №5. За введеним номером дня тижня визначити його назву (рис. 6.7).

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

private void button1_Click(object sender, EventArgs e)
        {
            int n = int.Parse(textBox1.Text);
            switch (n)
            {
                case 1:
                    label2.Text = "Понеділок";
                    break;
                case 2:
                    label2.Text = "Вівторок";
                    break;
                case 3:
                    label2.Text = "Середа";
                    break;
                case 4:
                    label2.Text = "Четвер";
                    break;
                case 5:
                    label2.Text = "П’ятниця";
                    break;
                case 6:
                    label2.Text = "Субота";
                    break;
                case 7:
                    label2.Text = "Неділя";
                    break;
                default:
                    label2.Text = "Помилка введення!";
                    break;
            }
        }

Блок default в даній структурі є не обов’язковим.

Програмування на C#
рис. 6.8

Завдання №6. За введеним номером дня тижня визначити робочий цей день чи вихідний. Слово “робочий” потрібно вивести чорним кольором, а ”вихідний” – червоним (рис. 6.8).

В даній задачі для вхідних даних від 1 до 5 програма повинна виконувати однакові дії. Аналогічно, для введених значень 6 і 7 дії теж будуть однаковими. В таких випадках оператор вибору можна записувати наступним чином:

private void button1_Click(object sender, EventArgs e)
        {
            int n = int.Parse(textBox1.Text);
            switch (n)
            {
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                    label2.ForeColor = Color.Black;
                    label2.Text = "Робочий";
                    break;
                case 6:
                case 7:
                    label2.ForeColor = Color.Red;
                    label2.Text = "Вихідний";
                    break;
                default:
                    label2.Text = "Помилка введення!";
                    break;
            }
        }

Тернарний оператор ? :

Для більш короткого запису команди if – else в мові C# можна використовувати тернарний оператор, який має такий вигляд:

		Умова ? дія1 : дія2;
			

Дві наступних задачі розв’яжемо, використавши тернарний оператор (рішення lesson_6, проект task_7, task_8).

Завдання №7. Визначити більше з двох заданих різних чисел. (рис. 6.9).

Програмування на C#
рис. 6.9

Програмний код розв’язання задачі:

private void button1_Click(object sender, EventArgs e)
        {
            int a = int.Parse(textBox1.Text);
            int b = int.Parse(textBox2.Text);
            int max = a > b ? a : b;
            label4.Text = max.ToString();
        }

Розглянемо інший приклад використання тернарного оператору.

Завдання №8. Відомо натуральне число. Визначити парне воно чи ні. (рис. 6.10).

Для того, щоб визначити парне число чи ні, проаналізуємо остачу від ділення даного числа на 2. Якщо остача рівна 0, то число парне, якщо ні – непарне.

private void button1_Click(object sender, EventArgs e)
        {
            byte a = byte.Parse(textBox1.Text);
            label2.Text = a % 2 == 0 ? "Парне" : "Непарне";
        }
Програмування на C#
рис. 6.10

Практичне завдання

Завдання №9 (рішення lesson_6, проект task_9). Відомо початкові та кінцеві показники спожитої електроенергії. Вартість 1кВт·год електроенергії становить 0,9грн, якщо обсяг споживання не перевищив 100кВт·год. Для понаднормових витрат тариф становить 1,68грн. Обчисліть кількість спожитої електроенергії за та поза нормою, суму до сплати. (рис. 6.11).

Програмування на C#
рис. 6.11

Завдання №10 (рішення lesson_6, проект task_10). Відомо довжини трьох відрізків. Визначити, чи можна з даних відрізків утворити трикутник. (рис. 6.12).

Програмування на C#
рис. 6.12

Завдання №11 (рішення lesson_6, проект task_11). За заданою температурою води потрібно визначити її агрегатний стан: «Твердий», «Рідкий» чи «Газоподібній». (рис. 6.13).

Програмування на C#
рис. 6.13

Завдання №12 (рішення lesson_6, проект task_12). Відомо номер місяця. Вивести на екран відповідну пору року. (рис. 6.14).

Програмування на C#
рис. 6.14

Консольна сторінка – розв'язування задач

Програмування на C#
рис. 6.15

Додамо до нашого рішення консольний проект task_13. Розв’яжемо задачу: відомо сторони трикутника (вводяться через пробіл), потрібно визначити прямокутний він чи ні (рис. 6.15).

Для зчитування чисел, введених через пробіл, використаємо метод Split - поділ рядка на підрядки.

Для того, щоб визначити, прямокутний трикутник чи ні, використаємо теорему Піфагора, для виведення відповіді – тернарний оператор. Програмний код може мати такий вигляд:

static void Main(string[] args)
        {
            Console.Write("Введiть сторони трикутника: ");
            string[] s = Console.ReadLine().Split(' ');
            int a = int.Parse(s[0]);
            int b = int.Parse(s[1]);
            int c = int.Parse(s[2]);
            Console.WriteLine(a * a == b * b + c * c || b * b == a * a + c * c ||
            c * c == b * b + a * a ? "Прямокутний": "Не прямокутний");
        }

Консольна сторінка – практичне завдання

Програмування на C#
рис. 6.16

Задача №14. Відомо коефіцієнти квадратного рівняння. Визначити скільки коренів має дане рівняння: 2, 1 або 0 (lesson_6, проект task_14). Рис. 6.16.

Олімпіадна сторінка – розв’язування задач

Задача №6279 – Кількість днів у місяці - https://www.e-olymp.com/uk/problems/6279

Вивести кількість днів в N–му місяці M–го року по григоріанському календарю.

Історичний факт: Наприкінці 1582 року папа Григорій XIII запровадив у католицьких країнах календар, у якому рік є високосним, якщо він кратний 4, але не кратний 100, або ж кратний 400.

Вхідні дані: Значення N та M (1 ≤ N ≤ 12, 1 ≤ M ≤ 2100).

Вихідні дані: Знайдена кількість днів.

Вхідні дані: 10 2013

Вихідні дані: 31

Розв’язок:

Для визначення кількості днів у лютому скористаємося тернарним оператором. Для всіх інших місяців використаємо оператор вибору switch.

static void Main(string[] args)
        {
            string[] s = Console.ReadLine().Split(' ');
            int m = int.Parse(s[0]);
            int y = int.Parse(s[1]);
            int v = ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) ? 29 : 28;
            switch (m)
            {
                case 1:
                case 3:
                case 5:
                case 7:
                case 8:
                case 10:
                case 12:
                    v = 31;
                    break;
                case 4:
                case 6:
                case 9:
                case 11:
                    v = 30;
                    break;
            }
            Console.WriteLine(v);
        }

Задача №911 – Квадратне рівняння - https://www.e-olymp.com/uk/problems/911

Скласти програму для розв’язання квадратного рівняння ax2 + bx + c = 0 (a ≠ 0).

Вхідні дані: У єдиному рядку задано через пропуск 3 цілі числа - коефіцієнти квадратного рівняння відповідно a, b та c. Значення коефіцієнтів не перевищують по модулю 100.

Вихідні дані: У єдиному рядку вивести у випадку відсутності коренів повідомлення "No roots" (без лапок), у випадку, якщо розв'язок містить один корінь вивести спочатку повідомлення "One root:" (без лапок), а далі через пропуск сам корінь, у випадку наявності двох коренів вивести спочатку повідомлення "Two roots:" (без лапок), а далі через пропуск спочатку менший, а потім більший корінь. Гарантується, що у випадку наявності розв'язків всі корені цілочисельні.

Вхідні дані: 1 -5 6

Вихідні дані: Two roots: 2 3

Вхідні дані: 1 5 6

Вихідні дані: Two roots: -3 -2

Розв’язок:

Для розв’язання даної задачі потрібно обчислити дискримінант квадратного рівняння, після чого розглянути три випадки:

Програмний код може мати наступний вигляд:

static void Main(string[] args)
        {
            string[] s = Console.ReadLine().Split(' ');
            int a = int.Parse(s[0]);
            int b = int.Parse(s[1]);
            int c = int.Parse(s[2]);
            int D = b * b - 4 * a * c;
            double x1, x2;
            if (D > 0)
            {
                x1 = (-b - Math.Sqrt(D)) / (2 * a);
                x2 = (-b + Math.Sqrt(D)) / (2 * a);
                if (x1 < x2)
                    Console.WriteLine("Two roots: {0} {1}", x1, x2);
                else Console.WriteLine("Two roots: {0} {1}", x2, x1);
            }
            else if (D == 0)
            {
                x1 = -b / (2 * a);
                Console.WriteLine("One root: " + x1);
            }
            else Console.WriteLine("No roots");
        }

Олімпіадна сторінка – завдання

Задача №918 – Яка чверть? - https://www.e-olymp.com/uk/problems/918

Задано точку з координатами х та у. Визначити, в якій координатній чверті вона розміщена.

Вхідні дані: У єдиному рядку через пропуск задано 2 дійсні числа - координати точки, значення координат по модулю не перевищують 100.

Вихідні дані: Єдине число - номер відповідної чверті, або 0, якщо однозначно визначити чверть неможливо.

Вхідні дані: 12 31

Вихідні дані: 1

Задача №6278 – Номери будинків - https://www.e-olymp.com/uk/problems/6278

З'ясувати, чи знаходяться будинки з номерами n та m на одній стороні вулиці.

Вхідні дані: Значення n та m (1 ≤ n, m ≤ 100).

Вихідні дані: Вивести 1, якщо будинки з номерами n та m знаходяться на одній стороні вулиці та 0 у протилежному випадку.

Вхідні дані: 1 2

Вихідні дані: 0