diff options
Diffstat (limited to 'week02')
| -rw-r--r-- | week02/exercise01.cpp | 17 | ||||
| -rw-r--r-- | week02/exercise02.cpp | 20 | ||||
| -rw-r--r-- | week02/exercise03.cpp | 15 | ||||
| -rw-r--r-- | week02/exercise04.cpp | 18 | ||||
| -rw-r--r-- | week02/exercise05.cpp | 11 | ||||
| -rw-r--r-- | week02/exercise06.cpp | 10 | ||||
| -rw-r--r-- | week02/exercise07.cpp | 29 | ||||
| -rw-r--r-- | week02/exercise08.cpp | 20 | ||||
| -rw-r--r-- | week02/exercise09.cpp | 29 | ||||
| -rw-r--r-- | week02/exercise10.cpp | 21 | ||||
| -rw-r--r-- | week02/exercise11.cpp | 21 |
11 files changed, 211 insertions, 0 deletions
diff --git a/week02/exercise01.cpp b/week02/exercise01.cpp new file mode 100644 index 0000000..539fa14 --- /dev/null +++ b/week02/exercise01.cpp @@ -0,0 +1,17 @@ +#include <iostream> + +int main() { + int n; + std::cin >> n; + + std::cout << "Със загуба bool " << (bool)n << std::endl; + std::cout << "Без загуба long long int " << (long long int)n << std::endl; + // Беше малко спорно дали от int към unsigned int губим информация + // Накрая приехме, че не губи, понеже всеки бит се запазва + std::cout << "Без загуба unsigned int " << (unsigned int)n << std::endl; + std::cout << "Със загуба char " << (char)n << std::endl; + std::cout << "Със загуба short int " << (short int)n << std::endl; + std::cout << "Без загуба double " << (double)n << std::endl; + std::cout << "Без загуба long int " << (long int)n << std::endl; + std::cout << "Със загуба unsigned char " << (unsigned char)n << std::endl; +} diff --git a/week02/exercise02.cpp b/week02/exercise02.cpp new file mode 100644 index 0000000..7589576 --- /dev/null +++ b/week02/exercise02.cpp @@ -0,0 +1,20 @@ +#include <iostream> + +int main() { + unsigned int n; + std::cin >> n; + // Чрез побитовото и (&) можем лесно да направим "филтър", ако бита в дясно е единица приемаме бита в ляво, иначе връщаме 0. + // От неговата дефиниция, ако имаме някакъв входен бит X, тогава X & 1 винаги ще връща X + // С примери: ако X=0, тогава 0 & 1 = 0; ако X=1, тогава 1 & 1 = 1 + // Обаче X & 0 винаги връща0 + // С примери: ако X=0, то 0 & 0 = 0; ако X = 1, то 1 & 0 = 0 + // Понеже не правим "сметкаджийска" операция, а повече използваме & за филтър, общоприето е да наричаме бита след & "маска". + // + // Тоест, да вземем най-десните 6 бита, означава да занулим останалите, тоест ще ползваме &, като в нашата маска + // трябва при най-десните 6 бита да са 1, докато останалите да са 0 + // + // Най-десните 6 бита съответстват на 2^5, 2^4, 2^3, 2^2, 2^1 и 2^0 + // Тоест, търсената маска е сумата на тези степени, което като го сметнем, излиза 31 + // Има и по-лесен начин да го изчислим, като забележим, че тази сума е равна на 2^6 - 1 + std::cout << (n & 31) << std::endl; +} diff --git a/week02/exercise03.cpp b/week02/exercise03.cpp new file mode 100644 index 0000000..009cf71 --- /dev/null +++ b/week02/exercise03.cpp @@ -0,0 +1,15 @@ +#include <iostream> + +int main() { + unsigned int a; + std::cin >> a; + // Отместването на дясно с всяка единица дели числото на 2, докато отместването на ляво умножава по 2 + // Нарочно 16 и 8 са степени на двойката + // + // Защо това се получава, еми, всеки бит се съпоставя с 2 на някаква степен, когато превръщаме в десетичен запис + // Примерно, да погледнем 101, десетично това е 1 * 2^2 + 0 * 2^1 + 1 * 2^0 + // Нека да разделим това уравнение на 2, това е 0 * 2^2 + 1 * 2^1 + 0 * 2^0 + // Нека сега да умоножим оригиналното по 2, 1 * 2^3 + 0 * 2^2 + 1 * 2^1 + 0 * 2^0 + // Сравнително очевидно се вижда, че деление и умножение на 2 измества битвоете надясно и наляво + std::cout << (a >> 4) << ' ' << (a << 3) << std::endl; +} diff --git a/week02/exercise04.cpp b/week02/exercise04.cpp new file mode 100644 index 0000000..2e83fbb --- /dev/null +++ b/week02/exercise04.cpp @@ -0,0 +1,18 @@ +#include <iostream> + +int main() { + unsigned int address; + std::cin >> address; + // Искаме най-левите 8 бита, означава че искаме да "издръпнем" десните 32-8=24 бита + int firstOctet = (address >> 24); + // Искаме вторите най-леви 8 бита, така че издръпваме най-левите 16 бита (32-16=16) + // и от тези 16 бита използваме маска, за да вземем най-десните 8 + // Маската ни десетично е 2^7 + 2^6 + 2^5 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0 + // За подробности с маски, вижте решението на 2ра задача + int secondOctet = (address >> 16) & 255; + // Същата идея, искаме третите най-леви 8 бита, така че дръпваме отдясно битвоте, така че + // търсените битове да са в най-дясно и с маска премахваме всичко освен тези 8 бита + int thirdOctet = (address >> 8) & 255; + int fourthOctet = address & 255; + std::cout << firstOctet << '.' << secondOctet << '.' << thirdOctet << '.' << fourthOctet << std::endl; +} diff --git a/week02/exercise05.cpp b/week02/exercise05.cpp new file mode 100644 index 0000000..059b530 --- /dev/null +++ b/week02/exercise05.cpp @@ -0,0 +1,11 @@ +#include <iostream> + +int main() { + int a, n; + std::cin >> a >> n; + // Булевите стойности true и false се изкарват на екрана като 1 и 0 съответно + // Има и по-кратък вариант на този израз, който е !(a % n), понеже ! e булев оператор, неговата + // стойност трябва да бъде булева, a % n се конвертира в булева стойност, като ако е 0 става false, иначе е true + // Така дефакто имаме, че ако а се дели на n имаме false, иначе имаме true, с една негация обръщаме това + std::cout << (a % n == 0) << std::endl; +} diff --git a/week02/exercise06.cpp b/week02/exercise06.cpp new file mode 100644 index 0000000..8261301 --- /dev/null +++ b/week02/exercise06.cpp @@ -0,0 +1,10 @@ +#include <iostream> + +int main() { + char input; + std::cin >> input; + // Някои хора използваха конкретните числови ASCII стойности в сравнението + // Бих казал че това е грешка, фундаментално знаците са числа, '0' и '9' се "превеждат" + // до конкретните ASCII стойности от C++ + std::cout << ('0' <= input && input <= '9') << std::endl; +} diff --git a/week02/exercise07.cpp b/week02/exercise07.cpp new file mode 100644 index 0000000..708ff20 --- /dev/null +++ b/week02/exercise07.cpp @@ -0,0 +1,29 @@ +#include <iostream> + +int main() { + int a, b, c; + std::cin >> a >> b >> c; + // Най-ефикасния начин да направим това, е да използваме 3 if-a и в тях да разменяме стойностите, + // така че накрая винаги a, b и c са в нарастващ ред + // Най лесния начин да обясня логиката е следния: + // Искаме a < b < c, това може да го сведем до точно 3 сравнение между две стойности, + // a < b, b < c и това което е изпълнено поради дефиницията на <, a < c + // a < b < c може да не е изпълнено, когато a < b, b < c и/или a < c не е изпълнено + // Затова разглеждаме точно тези случаи, които не биха били изпълнени, и с размяна ги правим изпълнени + if (a > b) { + int temp = a; + a = b; + b = temp; + } + if (b > c) { + int temp = b; + b = c; + c = temp; + } + if (a > c) { + int temp = a; + a = c; + c = temp; + } + std::cout << a << ' ' << b << ' ' << c << std::endl; +} diff --git a/week02/exercise08.cpp b/week02/exercise08.cpp new file mode 100644 index 0000000..e092134 --- /dev/null +++ b/week02/exercise08.cpp @@ -0,0 +1,20 @@ +#include <iostream> + +int main() { + int month; + std::cin >> month; + switch (month) { + case 1: std::cout << "January"; break; + case 2: std::cout << "February"; break; + case 3: std::cout << "March"; break; + case 4: std::cout << "April"; break; + case 5: std::cout << "May"; break; + case 6: std::cout << "June"; break; + case 7: std::cout << "July"; break; + case 8: std::cout << "August"; break; + case 9: std::cout << "September"; break; + case 10: std::cout << "October"; break; + case 11: std::cout << "November"; break; + case 12: std::cout << "December"; break; + } +} diff --git a/week02/exercise09.cpp b/week02/exercise09.cpp new file mode 100644 index 0000000..e53d427 --- /dev/null +++ b/week02/exercise09.cpp @@ -0,0 +1,29 @@ +#include <iostream> + +int main() { + double price; + std::cin >> price; + + // Има два метода да се реши тази задача + // или (int)(price * 100) и price % x (където x е 50 или 20 или 10 или 5 или 1) + // или (int)(price / 0.x) и price -= (int)(price / 0.x) (където х е 5 или 2 или 1 или 05 или 01) + // Втория вариант е малко по-общ, затова него ще имплементирам + int divided = price / 0.5; + std::cout << "0.5 " << divided; + price -= divided * 0.5; + + divided = price / 0.2; + std::cout << " 0.2 " << divided; + price -= divided * 0.2; + + divided = price / 0.1; + std::cout << " 0.1 " << divided; + price -= divided * 0.1; + + divided = price / 0.05; + std::cout << " 0.05 " << divided; + price -= divided * 0.05; + + divided = price / 0.01; + std::cout << " 0.01 " << divided << std::endl; +} diff --git a/week02/exercise10.cpp b/week02/exercise10.cpp new file mode 100644 index 0000000..434aaa0 --- /dev/null +++ b/week02/exercise10.cpp @@ -0,0 +1,21 @@ +#include <iostream> + +int main() { + int signals; + std::cin >> signals; + + int leftSignal = signals / 1000; + int rightSignal = signals % 1000; + + // difference е дефакто абсолютната стойност на leftSignal - rightSignal + int difference = leftSignal - rightSignal; + if (difference < 0) + difference *= -1; + + if (difference <= 3) + std::cout << "Follow heading" << std::endl; + else if (leftSignal < rightSignal) + std::cout << "Turn left" << std::endl; + else + std::cout << "Turn right" << std::endl; +} diff --git a/week02/exercise11.cpp b/week02/exercise11.cpp new file mode 100644 index 0000000..7d1de63 --- /dev/null +++ b/week02/exercise11.cpp @@ -0,0 +1,21 @@ +#include <iostream> + +int main() { + // Много не съм ползвал константи в решенията, не защото няма смисъл да се прави, а така някои неща по-лесно се виждат + const int LIGHT_SPEED = 29; + + int timeSent, firstSatelliteCoord, firstSatelliteTimeRecv, secondSatelliteCoord, secondSatelliteTimeRecv; + std::cin >> timeSent >> firstSatelliteCoord >> firstSatelliteTimeRecv >> secondSatelliteCoord >> secondSatelliteTimeRecv; + + int distanceToFirst = (firstSatelliteTimeRecv - timeSent) / 2 * LIGHT_SPEED; + int distanceToSecond = (secondSatelliteTimeRecv - timeSent) / 2 * LIGHT_SPEED; + + // Повтарям логиката тука: имаме 4 възможни точни, първия сателит +- дистаниця и втория сателит +- дистанция + // Понеже данните не лъжат, трябва две от тези 4 възможности да съвпадат, и това проверяваме + // Допускаме че входа е валиден, така че това работи + if (firstSatelliteCoord + distanceToFirst == secondSatelliteCoord + distanceToSecond || + firstSatelliteCoord + distanceToFirst == secondSatelliteCoord - distanceToSecond) + std::cout << (firstSatelliteCoord + distanceToFirst) << std::endl; + else + std::cout << (firstSatelliteCoord - distanceToSecond) << std::endl; +} |
