Глава 3.2. Прости проверки – изпитни задачи
В предходната глава разгледахме условните конструкции в езика C#, чрез които можем да изпълняваме различни действия в зависимост от някакво условие. Споменахме още какъв е обхватът на една променлива (нейният scope
), както и как постъпково да проследяваме изпълнението на нашата програма (т.нар. дебъгване). В настоящата глава ще упражним работата с логически проверки, като разгледаме някои задачи, давани на изпити. За целта нека първо си припомним конструкцията на логическата проверка:
if (булев израз)
{
// тяло на условната конструкция;
}
else
{
// тяло на else-конструкция;
}
if
проверките се състоят от:
if
клауза- булев израз - променлива от булев тип (
bool
) или булев логически израз (израз, който връща резултатtrue/false
) - тяло на конструкцията - съдържа произволен блок със сорс код
else
клауза и нейният блок със сорс код (незадължително)
Изпитни задачи
След като си припомнихме как се пишат условни конструкции, да решим няколко задачи, за да получим практически опит с if-else
-конструкцията.
Задача: цена за транспорт
Студент трябва да пропътува n километра. Той има избор измежду три вида транспорт:
- Такси. Начална такса: 0.70 лв. Дневна тарифа: 0.79 лв./км. Нощна тарифа: 0.90 лв./км.
- Автобус. Дневна / нощна тарифа: 0.09 лв./км. Може да се използва за разстояния минимум 20 км.
- Влак. Дневна / нощна тарифа: 0.06 лв./км. Може да се използва за разстояния минимум 100 км.
Напишете програма, която въвежда броя километри n и период от деня (ден или нощ) и изчислява цената на най-евтиния транспорт.
Входни данни
От конзолата се четат два реда:
- Първият ред съдържа числото n – брой километри – цяло число в интервала [1 … 5000].
- Вторият ред съдържа дума “day” или “night” – пътуване през деня или през нощта.
Изходни данни
Да се отпечата на конзолата най-ниската цена за посочения брой километри.
Примерен вход и изход
Вход | Изход | Вход | Изход |
---|---|---|---|
5 day |
4.65 | 7 night |
7 |
Вход | Изход | Вход | Изход |
---|---|---|---|
25 day |
2.25 | 180 night |
10.8 |
Насоки и подсказки
Ще прочетем входните данни и в зависимост от разстоянието ще изберем най-евтиния транспорт. За целта ще използваме няколко проверки.
Обработка на входните данни
В условието на задачата е дадена информация за входа и изхода. Съответно, първите два реда от решението ще съдържат декларирането и инициализирането на двете променливи, в които ще пазим стойностите на входните данни.
За първия ред е упоменато, че съдържа цяло число, затова и променливата, която ще бъде декларирана, е от тип int
. За втория ред указанието е, че съдържа дума, съответно променливата е от тип string
.
Преди да започнем проверките е нужно да декларираме и една променлива, в която ще пазим стойността на цената за транспорт.
Извършване на проверки и съответните изчисления
След като вече сме декларирали и инициализирали входните данни и променливата, в която ще пазим стойността на цената, трябва да преценим кои условия от задачата първо ще бъдат проверени.
От условието е видно, че тарифите на две от превозните средства не зависят от това дали е ден или нощ, но тарифата на единия превоз (такси) зависи. По тази причина първата проверка ще е именно дали е ден или нощ, за да стане ясно коя тарифа на таксито ще се използва. За целта декларираме още една променлива, в която ще пазим стойността на тарифата на таксито.
За да изчислим тарифата на таксито, ще използваме проверка от типа if-else
и чрез нея променливата за цената на таксито ще си присвои стойност.
След като е направено и това, вече може да пристъпим към изчислението на самата цена за транспорта. Ограниченията, които присъстват в условието на задачата, са относно разстоянието, което студента иска да пропътува. По тази причина, ще построим if-else
конструкция, с чиято помощ ще открием цената за транспорта в зависимост от подадените километри.
Първо правим проверка дали километрите са под 20, тъй като от условието е видно, че под 20 километра студента би могъл да използва само такси. Ако условието на проверката е вярно (връща true
), променливата, която е създадена, за да пази стойността на цената на транспорта (price
), ще си присвои съответната стойност. Тази стойност е равна на първоначалната такса, която събираме с неговата тарифа, умножена по разстоянието, което студента трябва да измине.
Ако условието на променливата не е вярно (връща false
), следващата стъпка е програмата ни да провери дали километрите са под 100. Правим това, защото от условието е видно, че в този диапазон може да се използва и автобус като транспортно средство. Цената за километър на автобуса е по-ниска от тази на таксито. Следователно, ако резултата от проверката е верен, то в блок тялото на else if
, на променливата за цената на транспорта (price
) трябва да присвоим стойност, равна на резултата от умножението на тарифата на автобуса по разстоянието.
Ако и тази проверка не даде true
като резултат, остава в тялото на else
на променливата за цена да присвоим стойност, равна на резултата от умножението на разстоянието по тарифата на влака. Това се прави, тъй като влакът е най-евтиния вариант за транспорт при даденото разстояние.
Отпечатване на изходните данни
След като сме направили проверките за разстоянието и сме изчислили цената на най-евтиния транспорт, следва да я отпечатаме. В условието на задачата няма изисквания как да бъде форматиран резултата и по тази причина ще отпечатаме само променливата.
Тестване в Judge системата
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/507#0.
Задача: тръби в басейн
Басейн с обем V има две тръби, от които се пълни. Всяка тръба има определен дебит (литрите вода, минаващи през една тръба за един час). Работникът пуска тръбите едновременно и излиза за N часа. Напишете програма, която изкарва състоянието на басейна, в момента, когато работникът се върне.
Входни данни
От конзолата се четат четири реда:
- Първият ред съдържа числото V – обем на басейна в литри – цяло число в интервала [1 … 10000].
- Вторият ред съдържа числото P1 – дебит на първата тръба за час – цяло число в интервала [1 … 5000].
- Третият ред съдържа числото P2 – дебит на втората тръба за час – цяло число в интервала [1 … 5000].
- Четвъртият ред съдържа числото H – часовете, в които работникът отсъства – число с плаваща запетая в интервала [1.0 … 24.00].
Изходни данни
Да се отпечата на конзолата едно от двете възможни състояния:
- До колко се е запълнил басейнът и коя тръба с колко процента е допринесла. Всички проценти да се форматират до цяло число (без закръгляне).
- "The pool is [x]% full. Pipe 1: [y]%. Pipe 2: [z]%."
- Ако басейнът се е препълнил – с колко литра е прелял за даденото време, число с плаваща запетая.
- "For [x] hours the pool overflows with [y] liters."
Имайте предвид, че поради закръглянето до цяло число се губят данни и e нормално сборът на процентите да е 99%, а не 100%.
Примерен вход и изход
Вход | Изход | Вход | Изход |
---|---|---|---|
1000 100 120 3 |
The pool is 66% full. Pipe 1: 45%. Pipe2: 54%. | 100 100 100 2.5 |
For 2.5 hours the pool overflows with 400 liters. |
Насоки и подсказки
За да решим задачата, ще прочетем входа, ще извършим няколко проверки и изчисления и ще отпечатаме резултата.
Обработка на входните данни
От условието на задачата виждаме, че в програмата ни трябва да има четири реда, от които четем входните данни. Чрез първите три ще въвеждаме цели числа и по тази причина променливите, в които ще запазваме стойностите, ще бъдат от тип int
. За четвъртия ред ни е казано, че ще бъде число, което е с плаваща запетая, затова и променливата, която ще използваме, е от тип double
.
Следващата ни стъпка е да декларираме и инициализираме променлива, в която ще изчислим с колко литра се е напълнил басейна за времето, в което работникът е отсъствал. Изчисленията ще направим като съберем стойностите на дебита на двете тръби и ги умножим по часовете, които са ни зададени като вход.
Извършване на проверки и обработка на изходните данни
След като вече имаме и стойността на количеството вода, което е минало през тръбите, следва стъпката, в която трябва да сравним това количество с обема на самия басейн.
Това ще направим с проста if-else
проверка, в която условието ще е дали количеството вода е по-малко от обема на басейна. Ако проверката върне true
, то трябва да разпечатаме един ред, който да съдържа в себе си съотношението между количеството вода, минало през тръбите, и обема на басейна, както и съотношението на количеството вода от всяка една тръба спрямо обема на басейна.
Съотношението е нужно да бъде изразено в проценти, затова и всички изчисления до момента в този ред ще бъдат умножени по 100. Стойностите ще бъдат вмъкнати с placeholder-и и тъй като има условие резултата в проценти да се форматира до две цифри след десетичния знак без закръгляне, то за целта ще използваме метода Math.Truncate(…)
.
Ако проверката обаче върне резултат false
, то това означава, че количеството вода е по-голямо от обема на басейна, съответно той е прелял. Отново изхода трябва да е на един ред, но този път съдържа в себе си само две стойности - тази на часовете, в които работникът е отсъствал, и количеството вода, което е разлика между влязлата вода и обема на басейна.
Тестване в Judge системата
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/507#1.
Задача: поспаливата котка Том
Котката Том обича по цял ден да спи, за негово съжаление стопанинът му си играе с него винаги когато има свободно време. За да се наспи добре, нормата за игра на Том е 30 000 минути в година. Времето за игра на Том зависи от почивните дни на стопанина му:
- Когато е на работа, стопанинът му си играе с него по 63 минути на ден.
- Когато почива, стопанинът му си играе с него по 127 минути на ден.
Напишете програма, която въвежда броя почивни дни и отпечатва дали Том може да се наспи добре и колко е разликата от нормата за текущата година, като приемем че годината има 365 дни.
Пример: 20 почивни дни -> работните дни са 345 (365 – 20 = 345). Реалното време за игра е 24 275 минути (345 * 63 + 20 * 127). Разликата от нормата е 5 725 минути (30 000 – 24 275 = 5 725) или 95 часа и 25 минути.
Входни данни
Входът се чете от конзолата и се състои от едно цяло число - броят почивни дни в интервала [0 … 365].
Изходни данни
На конзолата трябва да се отпечатат два реда.
- Ако времето за игра на Том е над нормата за текущата година:
- На първия ред отпечатайте: “Tom will run away”
- На втория ред отпечатайте разликата от нормата във формат:
“{H} hours and {M} minutes more for play”
- Ако времето за игра на Том е под нормата за текущата година:
- На първия ред отпечатайте: “Tom sleeps well”
- На втория ред отпечатайте разликата от нормата във формат:
“{H} hours and {M} minutes less for play”
Примерен вход и изход
Вход | Изход | Вход | Изход |
---|---|---|---|
20 | Tom sleeps well 95 hours and 25 minutes less for play |
113 | Tom will run away 3 hours and 47 minutes for play |
Насоки и подсказки
За да решим задачата, ще прочетем входа, ще извършим няколко проверки и изчисления и ще отпечатаме резултата.
Обработка на входните данни и прилежащи изчисления
От условието на задачата виждаме, че входните данни ще бъдат прочетени само от един ред, който ще съдържа в себе си едно цяло число в интервала [0 … 365]. По тази причина ще използваме променлива от тип int
.
За да решим задачата, първо трябва да изчислим колко общо минути стопанинът на Том си играе с него. От условието виждаме, че освен в почивните дни, поспаливата котка трябва да си играе и в работните за стопанина му. Числото, което прочитаме от конзолата, е това на почивните дни.
Следващата ни стъпка е с помощта на това число да изчислим колко са работните дни на стопанина, тъй като без тях не можем да стигнем до общото количество минути за игра. Щом общият брой на дните в годината е 365, а броят на почивните дни е Х, то това означава, че броят на работните дни е 365 - X. Разликата ще запазим в нова променлива, която ще използваме само за тази стойност.
След като вече имаме количествата дни за игра, то вече можем да изчислим времето за игра на Том в минути. Неговата стойност е равна на резултата от умножението на работните дни по 63 минути (в условието е зададено, че в работни дни, времето за игра е 63 минути на ден) събран с резултата от умножението на почивните дни по 127 минути (в условието е зададено, че в почивните дни, времето за игра е 127 минути на ден).
В условието на задачата за изхода виждаме, че ще трябва да разпечатаме разликата между двете стойности в часове и минути. За тази цел от общото време за игра ще извадим нормата от 30 000 минути и получената разлика ще запишем в нова променлива. След това тази променлива ще разделим целочислено на 60, за да получим часовете, а след това, за да открием колко са минутите ще използваме модулно деление с оператора %
, като отново ще разделим променливата на разликата с 60.
Тук трябва да отбележим, че ако полученото количество време игра на Том е по-малко от 30 000, при изваждането на нормата от него ще получим число с отрицателен знак. За да неутрализираме знака в двете деления по-късно, ще използваме метода Math.Abs(…)
при намирането на разликата.
Извършване на проверки
Времето за игра вече е изчислено, което ни води до следващата стъпка - сравняване на времето за игра на Том с нормата, от която зависи дали котката може да се наспива добре. За целта ще използваме if-else
проверка, като в if
клаузата ще проверим дали времето за игра е по-голямо от 30 000 (нормата).
Обработка на изходните данни
Какъвто и резултат да ни върне проверката, то трябва да разпечатаме колко е разликата в часове и минути. Това ще направим с placeholder и променливите, в които изчислихме стойностите на часовете и минутите, като форматирането ще е според условието за изход.
Тестване в Judge системата
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/507#2.
Задача: реколта
От лозе с площ X квадратни метри се заделя 40% от реколтата за производство на вино. От 1 кв.м. лозе се изкарват Y килограма грозде. За 1 литър вино са нужни 2,5 кг. грозде. Желаното количество вино за продан е Z литра.
Напишете програма, която пресмята колко вино може да се произведе и дали това количество е достатъчно. Ако е достатъчно, остатъкът се разделя по равно между работниците на лозето.
Входни данни
Входът се чете от конзолата и се състои от точно 4 реда:
- 1-ви ред: X кв.м е лозето – цяло число в интервала [10 … 5000].
- 2-ри ред: Y грозде за един кв.м. – реално число в интервала [0.00 … 10.00].
- 3-ти ред: Z нужни литри вино – цяло число в интервала [10 … 600].
- 4-ти ред: брой работници – цяло число в интервала [1 … 20].
Изходни данни
На конзолата трябва да се отпечата следното:
- Ако произведеното вино е по-малко от нужното:
- “It will be a tough winter! More {недостигащо вино} liters wine needed.”
* Резултатът трябва да е закръглен към по-ниско цяло число.
- “It will be a tough winter! More {недостигащо вино} liters wine needed.”
- Ако произведеното вино е повече от нужното:
- “Good harvest this year! Total wine: {общо вино} liters.”
* Резултатът трябва да е закръглен към по-ниско цяло число. - “{Оставащо вино} liters left -> {вино за 1 работник} liters per person.”
* И двата резултата трябва да са закръглени към по-високото цяло число.
- “Good harvest this year! Total wine: {общо вино} liters.”
Примерен вход и изход
Вход | Изход | Вход | Изход |
---|---|---|---|
650 2 175 3 |
Good harvest this year! Total wine: 208 liters. 33 liters left -> 11 liters per person. |
1020 1.5 425 4 |
It will be a tough winter! More 180 liters wine needed. |
Насоки и подсказки
За да решим задачата, ще прочетем входа, ще извършим няколко проверки и изчисления и ще отпечатаме резултата.
Обработка на входните данни и прилежащи изчисления
Първо трябва да проверим какви ще са входните данни и да изберем какви променливи ще използваме.
За да решим задачата е нужно да изчислим колко литра вино ще получим на база входните данни. От условието на задачата виждаме, че за да пресметнем количеството вино в литри, трябва първо да разберем какво е количеството грозде в килограми, което ще се получи от тази реколта. За тази цел ще декларираме една променлива, на която ще присвоим стойност, равна на 40% от резултата от умножението на площта на лозето и количеството грозде, което се получава от 1 кв. м.
След като сме извършили тези пресмятания, сме готови да пресметнем и количеството вино в литри, което ще се получи от тази реколта. За тази цел декларираме още една променлива, в която ще пазим това количество, а от условието стигаме до извода, че за да го пресметнем, е нужно да разделим количеството грозде в кг на 2.5.
Извършване на проверки и обработка на изходните данни
Вече сме направили нужните пресмятания и следващата стъпка е да проверим дали получените литри вино са достатъчни. За целта ще използваме проста условна конструкция от типа if-else
, като в условието ще проверим дали литрите вино от реколтата са повече от или равни на нужните литри.
Ако проверката върне резултат true
, от условието на задачата виждаме, че на първия ред трябва да разпечатаме виното, което сме получили от реколтата. За да спазим условието тази стойност да бъде закръглена до по-ниското цяло число, ще използваме метода Math.Floor(…)
при разпечатването й чрез placeholder.
На втория ред има изискване да разпечатаме резултатите, като ги закръглим към по-високото цяло число, което ще направим с метода Math.Ceiling(…)
. Стойностите, които трябва да разпечатаме, са на оставащото количество вино и количеството вино, което се пада на един работник. Оставащото количество вино е равно на разликата между получените литри вино и нужните литри вино. Стойността на това количество ще изчислим в нова променлива, която ще декларираме и инициализираме в блок тялото на if
, преди разпечатването на първия ред. Количеството вино, което се полага на един работник, ще изчислим като оставащото вино го разделим на броя на работниците.
Ако проверката ни върне резултат false
от условието на задачата виждаме, че трябва да разпечатаме разликата от нужните литри и получените от тази реколта литри вино. Има условие резултата да е закръглен към по-ниското цяло число, което ще направим с метода Math.Floor(…)
.
Тестване в Judge системата
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/507#3.
Задача: фирма
Фирма получава заявка за изработването на проект, за който са необходими определен брой часове. Фирмата разполага с определен брой дни. През 10% от дните служителите са на обучение и не могат да работят по проекта. Един нормален работен ден във фирмата е 8 часа. Проектът е важен за фирмата и всеки служител задължително работи по проекта в извънработно време по 2 часа на ден.
Часовете трябва да са закръглени към по-ниско цяло число (например → 6.98 часа се закръглят на 6 часа).
Напишете програма, която изчислява дали фирмата може да завърши проекта навреме и колко часа не достигат или остават.
Входни данни
Входът се чете от конзолата и съдържа точно 3 реда:
- На първия ред са необходимите часове – цяло число в интервала [0 … 200 000].
- На втория ред са дните, с които фирмата разполага – цяло число в интервала [0 … 20 000].
- На третия ред е броят на всички служители – цяло число в интервала [0 … 200].
Изходни данни
Да се отпечата на конзолата един ред:
- Ако времето е достатъчно:
- "Yes!{оставащите часове} hours left.".
- Ако времето НЕ Е достатъчно:
- "Not enough time!{недостигащите часове} hours needed.".
Примерен вход и изход
Вход | Изход | Вход | Изход |
---|---|---|---|
90 7 3 |
Yes!99 hours left. | 99 3 1 |
Not enough time!72 hours needed. |
Насоки и подсказки
За да решим задачата, ще прочетем входа, ще извършим няколко проверки и изчисления и ще отпечатаме резултата.
Обработка на входните данни
За решението на задачата е нужно първо да преценим какви типове променливи ще използваме за входните данни.
Помощни изчисления
Следващата стъпка е да изчислим количеството на работните часове като умножим работните дни по 8 (всеки ден се работи по 8 часа) с броя на работниците и ги съберем с извънработното време. Работните дни са равни на 90% от дните, с които фирмата разполага. Извънработното време е равно на резултата от умножението на броя на служителите с 2 (възможните часове извънработно време), като това също се умножава по броя на дните, с които фирмата разполага. От условието на задачата виждаме, че има условие часовете да са закръглени към по-ниско цяло число, което ще направим с метода Math.Floor(…)
.
Извършване на проверки
След като сме направили изчисленията, които са ни нужни за да разберем стойността на работните часове, следва да направим проверка дали тези часове достигат или остават допълнителни такива.
Ако времето е достатъчно, разпечатваме резултата, който се изисква в условието на задачата, а именно разликата между работните часове и необходимите часове за завършване на проекта.
Ако времето не е достатъчно, разпечатваме допълнителните часове, които са нужни за завършване на проекта и са равни на разликата между часовете за проекта и работните часове.
Тестване в Judge системата
Тествайте решението си тук: https://judge.softuni.org/Contests/Practice/Index/507#4.