C Zbior Zadan Z Rozwiazaniami Tomasz Jasniewski Helion
C Zbior Zadan Z Rozwiazaniami Tomasz Jasniewski Helion
C Zbior Zadan Z Rozwiazaniami Tomasz Jasniewski Helion
Helion S.A.
ul. Kościuszki 1c, 44-100 Gliwice
tel. 32 231 22 19, 32 230 98 63
e-mail: [email protected]
WWW: http://helion.pl (księgarnia internetowa, katalog książek)
Drogi Czytelniku!
Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres
http://helion.pl/user/opinie/cppzbz_ebook
Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję.
ISBN: 978-83-8322-803-7
26589ec988c76404b19a97e88c6609a5
2
Spis treści
O autorze… i programowaniu 5
Powód powstania zbioru 5
Podziękowania 6
Charakterystyka opracowanego zbioru zadań 6
To musisz przeczytać! 7
Dane do zadań 9
Rozwiązania 45
Część 1. (#1) Ślady życia 45
Część 2. (#2) Pierwotniaczki 65
26589ec988c76404b19a97e88c6609a5
2
4 SPIS TREŚCI
26589ec988c76404b19a97e88c6609a5
2
O autorze… i programowaniu
26589ec988c76404b19a97e88c6609a5
2
6 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
a także nie posiadając żadnego doświadczenia, stawia pytania: „Co mam teraz
robić?”, „Jaki program napisać?”, „Jak wykorzystać to, co było na lekcjach?”. Jednym
słowem: „Co zrobić z tą małą porcją wiedzy, którą posiadam? Jak ją zwiększyć?”.
W odpowiedzi na to pytanie powstawał ten zbiór zadań. Jest to próba ukierun-
kowania, uporządkowania i wzbogacenia tego czasu, który spędzamy pomiędzy
pierwszą lekcją z Hello World! a pierwszą stworzoną samodzielnie przez nas
aplikacją, którą sprzedaliśmy. Czasu radosnej nauki, kiedy wszystko wydaje się
możliwe, a ogranicza nas tylko wyobraźnia.
Podziękowania
Praca nad zbiorem to mieszanina frajdy i zmęczenia i kiedy do głosu dochodzi
to drugie, przeoczenie błędów jest nieuniknione. Dziękuję Grzegorzowi Gilowi
za udzielenie mi pomocy w wyłapywaniu błędów i za podrzucenie kilku alter-
natywnych rozwiązań zadań.
26589ec988c76404b19a97e88c6609a5
2
O AUTORZE… I PROGRAMOWANIU 7
To musisz przeczytać!
Ten fragment zbioru zawiera bardzo ważne informacje dotyczące zadań.
Przeczytaj je, inaczej możesz nie rozumieć oznaczeń stosowanych w zbiorze,
a treść zadań może rodzić niepotrzebne pytania.
Jeżeli zadanie jasno czegoś nie określa, to oznacza, że masz dowolność
interpretacji treści zgodnie z logiką jego rozwiązania. Jeżeli masz lepszy
pomysł na zadanie, wykonaj je raz jeszcze! Jeżeli zadanie zrodziło w Two-
jej głowie pomysł na jakiś wspaniały program, napisz go! Takie podejście
pozwala wycisnąć maksimum z zadania i zwiększyć Twoje umiejętności.
Nasz mózg zgłębia narzędzie, którego używa, z czasem zwiększając moż-
liwości tegoż narzędzia poprzez kreatywne i twórcze pomysły. Gdy nagle
dostrzegasz lepsze rozwiązanie, jest to coś naturalnego i nie należy tego
pomijać, ale trzeba iść za ciosem i zrobić to! Tak rodzą się najlepsi.
Liczba w nawiasie kwadratowym w nagłówku zadania (np. [6]) to suge-
rowana liczba punktów za zadanie, a zarazem przybliżona informacja
o trudności zadania w danej grupie umiejętności. Miarą trudności jest
moje widzi-mi-się, zatem jest to miara subiektywna. Wagi punktów w róż-
nych grupach są różne. Punktacja zadania (np. [1]) w grupie początkowej
ma mniejszą wagę i mniejszy stopień trudności od takiej samej punktacji
w grupie późniejszej, która wymaga większej porcji umiejętności. Nie-
kiedy punktacja jednego zadania jest rozbita i w treści występują takie
oznaczenia jak np. [3,], a następnie np. [2], co wskazuje na to, że w zada-
niu są etapy punktowane oddzielnie. Punktacja może wesprzeć nauczy-
ciela przy planowaniu np. sprawdzianu, proszę ją jednak traktować
orientacyjnie. Zatem [3,] i [2] to razem [5] punktów możliwych za po-
szczególne fragmenty zadania.
We wszystkich zadaniach zakładamy poprawność danych (podobnie jest
na maturze!). Programy z rozwiązaniami zazwyczaj nie zawierają ob-
sługi błędów. Jeżeli dane początkowe mają być np. liczbami dodatnimi,
to takimi dokładnie mają być. Czasami jednak w rozwiązaniu wykonuję
26589ec988c76404b19a97e88c6609a5
2
8 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
26589ec988c76404b19a97e88c6609a5
2
O AUTORZE… I PROGRAMOWANIU 9
Dane do zadań
Poniższy link umożliwi Ci pobieranie plików z danymi do zadań:
https://ftp.helion.pl/przyklady/cppzbz.zip
26589ec988c76404b19a97e88c6609a5
2
10 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
26589ec988c76404b19a97e88c6609a5
2
CZĘŚĆ 1. (#1) Ślady życia (40 zadań)
26589ec988c76404b19a97e88c6609a5
2
12 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zwroty „uwzględnij małe litery angielskie”, „uwzględnij tylko cyfry” i inne podobne
zwroty oznaczają, że wprowadzane dane mogą być tylko takie i nie zakładamy wy-
korzystania innych.
Zadania
Zadanie 1.1 [2]
Pobierz z klawiatury trzy nieujemne liczby całkowite. Znajdź największą z nich.
Wyświetl sumę pozostałych liczb tyle razy, ile wynosi wartość największej
liczby. [2]
Zaprojektuj program tak, aby w przypadku dzielenia przez zero informował o tym
i nie wykonywał działania.
26589ec988c76404b19a97e88c6609a5
2
CZĘŚĆ 1. (#1) ŚLADY ŻYCIA (40 ZADAŃ) 13
Sprawdź też operację przy zamianie liczb miejscami. Jeżeli wynik różni się od wcze-
śniejszego, wyświetl oba wyniki. Jeżeli jest taki sam, wyświetl go tylko jeden raz.
Na przykład dla liczb 5 i 2 oraz znaku / (dzielenie) trzeba wyświetlić 5/2 i 2/5, po-
nieważ dają różny wynik.
26589ec988c76404b19a97e88c6609a5
2
14 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
26589ec988c76404b19a97e88c6609a5
2
CZĘŚĆ 1. (#1) ŚLADY ŻYCIA (40 ZADAŃ) 15
26589ec988c76404b19a97e88c6609a5
2
16 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Każda cyfra (0 lub 1) to kolejny dzień udany (1) lub nieudany (0).
26589ec988c76404b19a97e88c6609a5
2
CZĘŚĆ 1. (#1) ŚLADY ŻYCIA (40 ZADAŃ) 17
Pytania znajdują się w komentarzach i zostały oznaczone jako a), b), c) i d). [1]
26589ec988c76404b19a97e88c6609a5
2
18 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
26589ec988c76404b19a97e88c6609a5
2
CZĘŚĆ 1. (#1) ŚLADY ŻYCIA (40 ZADAŃ) 19
26589ec988c76404b19a97e88c6609a5
2
20 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
26589ec988c76404b19a97e88c6609a5
2
CZĘŚĆ 2. (#2) Pierwotniaczki (75 zadań)
26589ec988c76404b19a97e88c6609a5
2
22 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
W tej części zbioru podczas rozwiązywania zadań twórz jak najwięcej funkcji. Oczy-
wiście z zachowaniem zdrowego rozsądku. Szukaj fragmentów kodu, który się po-
wtarza, i twórz z niego funkcje, opatrując je sugestywnymi nazwami. Trzy proste
funkcje, dobrze nazwane i wywołujące siebie, mogą być o wiele czytelniejsze niż
jedna, długa, zawiła i do tego źle nazwana.
Zadania
Zadanie 2.1 [1]
Wyświetl swoje imię w pętli tyle razy, ile jest w tym imieniu samogłosek (uwzględ-
nij sześć samogłosek, to jest "eyuioa"). [1]
Niektóre funkcje możesz sobie zachować, mogą bowiem przydać się w wielu za-
daniach — przykładowo: funkcje wyświetlające zawartość wektora czy generujące
wektory z losowymi liczbami i/lub losową wielkością.
26589ec988c76404b19a97e88c6609a5
2
CZĘŚĆ 2. (#2) PIERWOTNIACZKI (75 ZADAŃ) 23
26589ec988c76404b19a97e88c6609a5
2
24 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
26589ec988c76404b19a97e88c6609a5
2
CZĘŚĆ 2. (#2) PIERWOTNIACZKI (75 ZADAŃ) 25
Piramida ma być symetryczna, czyli środkowy znak '#' w każdej linii ma być w tej
samej pionowej linii/kolumnie. Na przykład dla n=5:
#
###
#####
Zadbaj o to, aby obie figury rysowała funkcja otrzymująca jako argumenty znak n. [3]
26589ec988c76404b19a97e88c6609a5
2
26 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Następnie zrób to samo, ale kwadrat ma być pusty w środku (spacje) i posiadać
tylko krawędzie. Znak '@' ponownie nie może znajdować się na krawędzi. [2]
#####
# @ #
# #
# #
#####
Każda kolejna część choinki ma mieć piramidkę o jeden wiersz dłuższą, a łączna
liczba piramid tworzących choinkę ma być równa N. Pierwsza piramidka two-
rząca czubek choinki ma być zawsze złożona z trzech linii. Przykład dla N=3:
#
###
#####
#
###
#####
#######
#
###
#####
#######
######### (N=3 -> trzy piramidki tworzące choinkę)
26589ec988c76404b19a97e88c6609a5
2
CZĘŚĆ 2. (#2) PIERWOTNIACZKI (75 ZADAŃ) 27
będą leżały: jeden nad wykresem funkcji liniowej, jeden pod nim, jeden na wy-
kresie. [2]
26589ec988c76404b19a97e88c6609a5
2
28 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
(Plik może mieć dowolną zawartość i długość zgodną z zasadami pliku. Po pro-
stu utwórz go samodzielnie/ręcznie. Możesz skorzystać z pliku utworzonego
w zadaniu 2.31). [1]
(Plik może mieć dowolną zawartość zgodną z zasadami pliku, po prostu utwórz
go samodzielnie/ręcznie lub pobierz plik 33_dane.txt.) [2]:
430;130
380;130
770;290
650;430
890;380
210;1000
26589ec988c76404b19a97e88c6609a5
2
CZĘŚĆ 2. (#2) PIERWOTNIACZKI (75 ZADAŃ) 29
26589ec988c76404b19a97e88c6609a5
2
30 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
(Plik może mieć dowolną zawartość zgodną z zasadami pliku, po prostu utwórz go
samodzielnie/ręcznie albo skopiuj linie z przykładu lub pobierz plik 35_dane.txt). [4]
Sugeruję przy zapisie stosować regułę: jeden element typu A umieszczony w jed-
nej linii. Przy załadowaniu każda linia to kolejna wartość w wektorze. Sposób
zapisania elementu jest dowolny i zakłada kreatywność. [3]
26589ec988c76404b19a97e88c6609a5
2
CZĘŚĆ 2. (#2) PIERWOTNIACZKI (75 ZADAŃ) 31
Zaprojektuj dwie uniwersalne funkcje konwertujące liczby jak wyżej, ale dla do-
wolnej podstawy systemowej (od 2 do 16, czyli nie tylko dla systemu dwójko-
wego, ale także dla innych, do szesnastkowego włącznie). [4]
26589ec988c76404b19a97e88c6609a5
2
32 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Dla poniższych danych istnieją dwa obszary. Sprawdź, czy Twój program je znajdzie.
Poniższy kod znajduje się w pliku 44_kod.txt.
-------------------------
vector<vector<string>> W = {
{"ebb","cbe","beb","bdd","fcf","eed","bdd","cfd","cec","fee","ebf","cba","bff","acf","aee"},
{"ddc","eee","cac","cca","daa","cce","cbd","cad","afa","ced","fcc","cdd","cca","cfc","afd"},
{"dad","afb","bae","ffd","dba","efd","bac","dda","cca","beb","add","fba","bbe","fbd","fab"},
{"dfd","bcd","ecc","bfb","efb","cbb","dcf","afb","aaf","fcd","dee","dba","dca","baa","cee"},
{"fab","fba","efc","dad","caf","bad","dba","afa","fbd","cbf","ccb","fda","cff","eac","bde"},
{"efa","eac","ada","edd","fcd","fae","dff","cab","eab","dcc","dbd","bac","bfe","efe","eec"},
{"ccc","bcc","fbf","afa","abc","cde","fec","faa","bfe","cac","acd","dad","eca","bbe","afd"},
{"eba","abb","cfd","ccb","abc","def","ffc","ead","cdd","baf","bef","fbd","afb","bae","bfe"},
{"fcf","acf","bdc","baa","cdf","adf","edb","cab","ebe","faf","dee","ddc","ebd","aad","eaa"},
{"eee","aec","cbc","edd","bcf","fbb","acc","abf","dbc","cab","bcd","bbc","ebc","fee","fcd"},
{"cdc","cef","bfe","def","ede","ade","ade","dea","cbc","bce","bce","cad","fbb","dbb","ccb"},
{"feb","dba","afe","efa","add","aeb","bfc","bee","aca","acc","ebe","ead","ffa","baa","eca"},
{"eea","fcd","bdf","baf","fdb","fdb","ddd","bce","eed","edf","efc","fca","dff","def","abc"},
{"ebc","fcd","fad","cde","daf","eee","dfd","aaf","cff","dcc","aff","cfb","afc","bcd","cde"},
{"cca","afe","daf","ecf","cfd","cdb","bfe","aea","ffe","dae","bae","fce","ade","bbc","fcd"}}
;
Znajdź wszystkie wiersze i kolumny (znaki tworzące wiersz lub kolumnę) będące
palindromem. [3]
26589ec988c76404b19a97e88c6609a5
2
CZĘŚĆ 2. (#2) PIERWOTNIACZKI (75 ZADAŃ) 33
26589ec988c76404b19a97e88c6609a5
2
34 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
26589ec988c76404b19a97e88c6609a5
2
CZĘŚĆ 2. (#2) PIERWOTNIACZKI (75 ZADAŃ) 35
wszystkie sylaby mają w środku tę samą samogłoskę (w każdej same 'e' lub
w każdej same 'o'), a jeżeli imię składa się z nieparzystej liczby sylab, to każda
następna sylaba musi mieć inną samogłoskę w środku w odniesieniu do samo-
głoski z poprzedniej sylaby. Na podstawie tych informacji utwórz generator
imion w postaci funkcji, która zwraca losowe imię. Wygeneruj piętnaście imion
i przeczytaj je na głos pierwszej osobie, jaką zobaczysz. [2]
[1]
[1]
Zaprojektuj też funkcję dla dowolnego roku większego niż 2022. Uważaj na mecha-
nizm lat przestępnych! Funkcja jako argument powinna pobierać rok i liczbę
repezentującą dzień roku, np. f(2033,200) oznaczałoby: podaj informację o dniu
nr 200 w 2033 roku (zwróć datę oraz dzień roku, np. środa itd.). [4]
26589ec988c76404b19a97e88c6609a5
2
36 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Przy kopiowaniu danych między liczbami odstępy mogą być spacją lub tabula-
torem. W C++ znak tabulatora to "\t".
92 41 27 93 94 49
54 13 56 56 79 78
43 52 26 67 73 46
17 9 16 94 76 90
84 27 18 41 24 84
93 71 53 73 4 42
51 40 39 87 69 32
26589ec988c76404b19a97e88c6609a5
2
CZĘŚĆ 2. (#2) PIERWOTNIACZKI (75 ZADAŃ) 37
48 17 49 89 62 67
9 60 71 93 11 46
53 43 78 99 58 7
83 93 24 14 15 50
74 37 46 49 33 33
18 72 66 13 46 71
51 59 3 76 12 83
56 28 84 2 8 17
2 64 52 17 65 2
79 66 84 72 73 12
73 40 96 66 29 31
46 38 15 86 55 29
5 94 59 10 43 5
18 20 41 6 11 62
79 35 7 50 100 57
79 45 23 30 97 18
50 72 91 19 58 100
72 10 9 4 12 3
87 61 8 24 41 6
19 49 25 67 58 39
43 8 80 34 21 18
47 84 74 35 58 71
94 20 93 71 99 66
26589ec988c76404b19a97e88c6609a5
2
38 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Przy kopiowaniu danych między liczbami i napisami odstępy mogą być spacją
lub tabulatorem. W C++ znak tabulatora to "\t".
C 79 1
B 28 2
A 79 3
C 42 4
B 80 5
C 49 6
C 32 7
D 9 8
E 39 9
D 45 10
E 36 11
A 5 12
E 98 13
B 81 14
C 14 15
C 86 16
A 10 17
C 38 18
B 29 19
C 43 20
C 64 21
E 100 22
B 77 23
A 31 24
C 65 25
B 65 26
D 12 27
B 77 28
E 45 29
E 99 30
C 43 31
D 89 32
A 85 33
26589ec988c76404b19a97e88c6609a5
2
CZĘŚĆ 2. (#2) PIERWOTNIACZKI (75 ZADAŃ) 39
E 88 34
E 62 35
A 98 36
D 57 37
B 1 38
B 71 39
B 56 40
B 53 41
C 65 42
A 35 43
C 64 44
E 94 45
B 42 46
A 53 47
B 47 48
E 91 49
A 5 50
B 36 51
B 92 52
D 32 53
A 64 54
B 78 55
B 39 56
A 62 57
A 34 58
C 84 59
A 72 60
B 39 61
C 9 62
B 79 63
B 78 64
D 37 65
C 77 66
E 82 67
B 13 68
26589ec988c76404b19a97e88c6609a5
2
40 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
B 26 69
C 66 70
C 1 71
E 23 72
B 65 73
C 6 74
A 61 75
C 78 76
C 83 77
B 61 78
E 61 79
C 62 80
C 4 81
E 7 82
A 20 83
B 9 84
A 30 85
E 49 86
C 24 87
D 67 88
E 66 89
A 9 90
C 73 91
D 71 92
B 8 93
E 53 94
B 57 95
A 8 96
A 72 97
B 46 98
E 19 99
D 32 100
26589ec988c76404b19a97e88c6609a5
2
CZĘŚĆ 2. (#2) PIERWOTNIACZKI (75 ZADAŃ) 41
5 9 −1 4 8 2
7 4 0 ∗ 11 − 2 0
−3 5 2 3 5 3
2494
⎡3 0 2 2⎤
⎢ ⎥
⎢7 3 1 8⎥ ∗ 7
⎢1 2 3 4⎥
⎣9 6 3 1⎦
Mnożenie macierzy przez liczbę to mnożenie każdego jej elementu przez tę liczbę.
Mnożenie macierzy A i macierzy B (nie jest ono naprzemienne!) to mnożenie każ-
dego wiersza z macierzy A przez każdą kolumną z macierzy B. Mechanizm mnożenia
powinien być pokazany na lekcjach matematyki. Można go poszukać w Internecie.
26589ec988c76404b19a97e88c6609a5
2
42 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
która dla 0 < minL < maxL i niepustego napisu dict zwraca losowe słowo złożone
ze znaków zawartych w dict o długości nie mniejszej niż minL i nie większej niż
maxL. Na przykład sgen(2,4,"abc") może zwrócić 'bcca', ponieważ długość napisu
zawiera się pomiędzy 2 i 4 i składa się ze znaków napisu „abc”. [2,] Dla argumen-
tów sgen(5,10,"qazwsxedcrfvtgby") wylosuj 25 000 słów i umieść je w wektorze.
Następnie znajdź wszystkie słowa, które się powtórzyły.
Może się okazać, że nie ma takich słów. Algorytm może długo działać, w zależności
od pomysłu na jego realizację. Aby sprawdzić, czy Twój algorytm działa poprawnie,
możesz wylosować w ramach testu małą liczbę słów, np. 100 lub 200. [3]
Zastanów się, czy stworzony przez Ciebie algorytm szukania powtarzających się
słów da się jakoś przyśpieszyć. Czuj się w pełni wolny. Zwracane słowa możesz
przechowywać w inny sposób, jeżeli uznasz to za pomocne. Spróbuj ulepszać
algorytm, porównując czas działania kolejnych jego wersji.
To może się przydać (lecz nie musi): kasowanie z wektora jest optymalne, gdy usu-
wamy tylko ostatni element metodą pop_back(). Kasowanie elementów ze środka
lub z początku wymaga realokacji wektora w pamięci komputera. Przy dużych wek-
torach wiąże się to ze zwiększonym zużyciem zasobów.
26589ec988c76404b19a97e88c6609a5
2
CZĘŚĆ 2. (#2) PIERWOTNIACZKI (75 ZADAŃ) 43
26589ec988c76404b19a97e88c6609a5
2
44 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
test negacji: zwracać true, jeśli jedna liczba jest bitową negacją drugiej,
lub false w przeciwnym razie. Liczby reprezentowane przez string w obu
przypadkach powinny być takiej samej długości z uwzględnieniem po-
czątkowego zera; na przykład „00111” to negacja „11000” (true); [1,]
wskazanie liczby większej: zwracać liczbę bitową, która jest większa. [2]
Gdy dojdziemy do ostatniego elementu, traktujemy wektor, jak gdyby był cykliczny,
czyli po ostatniej liczbie kolejnym krokiem jest przejście do liczby pierwszej w tym
wektorze. Zwróć też uwagę, że gdy skasujemy element na końcu wektora, w celu
zachowania cykliczności przechodzimy na pozycję pierwszego elementu w wektorze,
tak jakby ten pierwszy „wskoczył” w miejsce właśnie skasowanego ostatniego.
Usuwanie elementów z wnętrza wektora nie jest operacją zbyt wydajną, przez wzgląd
na realokację wektora w pamięci. Jeżeli wiesz, jak korzystać z listy, możesz jej użyć
zamiast wektora.
26589ec988c76404b19a97e88c6609a5
2
Rozwiązania
Poniżej znajdują się proponowane rozwiązania, jednak nie muszą one być wcale
najlepsze. Porównaj je ze swoimi rozwiązaniami. Jeżeli moje są lepsze, to jest
wydajniejsze, bardziej czytelne, istotnie krótsze itd., to spróbuj je zrozumieć.
W ten sposób będziesz się uczyć i rozwijać.
Część 1.
(#1) Ślady życia
Zadanie #1.1
Przykładowe rozwiązanie 1.
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
unsigned a, b, c; // czyli unsigned int
unsigned suma = 0, maks;
cout << "Podaj kolejne 3 liczby całkowite nieujemne:";
cin >> a >> b >> c;
if (a > b) {
maks = a;
suma += b;
}
else {
26589ec988c76404b19a97e88c6609a5
2
46 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
maks = b;
suma += a;
}
if (maks > c) {
suma += c;
}
else {
suma += maks;
maks = c;
}
for (unsigned i = 1; i <= maks; i++) {
cout << suma << " ";
}
}
Przykładowe rozwiązanie 2.
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
unsigned a, b, c; // to samo co unsigned int
cout << "Podaj kolejne 3 liczby całkowite nieujemne:";
cin >> a >> b >> c;
unsigned suma = a + b + c;
unsigned maks = (a > b) ? a : b;
suma -= maks = (maks > c) ? maks : c;
while (maks--) {
cout << suma << " ";
}
}
Zadanie #1.2
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
int a;
cout << "Podaj liczbę całkowitą:";
cin >> a;
if (a % 2 == 0) cout << "tak\n";
else cout << "nie\n";
}
Zadanie #1.3
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
int a;
cout << "Podaj liczbę całkowitą:";
cin >> a;
if (a % 3 != 0 and a % 5 != 0) {
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 47
Zadanie #1.4
#include <iostream>
#include <vector>
using namespace std;
int main() {
setlocale(LC_ALL, "");
char znak;
cin >> znak; // wpisz tylko małe litery angielskie lub cyfry
vector<char> samogloski = { 'a','e','i','o','u','y' };
// kod '0' to 48, '1' to 49 itd.; przy porównaniu char jest rzutowany na liczbę
if (znak >= 48 and znak <= 48 + 9) {
cout << "Znak to cyfra.\n";
return 0; // zakończ program
}
bool samogloska = false;
for (auto s : samogloski)
if (znak == s) {
samogloska = true;
break;
}
if (samogloska) cout << "Znak to samogłoska.\n";
else cout << "Znak to spółgłoska.\n";
}
Zadanie #1.5
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
float a1, a2, a3, a4, a5;
cin >> a1 >> a2 >> a3 >> a4 >> a5;
if (a5 == 0.0) {
cout << "Dzielenie przez 0 to nie najlepszy pomysł.\n";
return 0; // opuść program
}
cout << "Wartość wyrażenia: " << (((a1 + a2) * a3) - a4) / a5 << endl;
// uwaga: starsze kompilatory mogą mieć problem z rzeczywistym porównaniem a5 == 0.0,
// gdyż liczba 0.0 może być przybliżeniem, a faktyczna
// wartość może wynosić np. 0.00000000000082790 itp.
}
26589ec988c76404b19a97e88c6609a5
2
48 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #1.6
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
unsigned ilep = 0, ilenp = 0;
int temp;
for (int i = 5; i--;) { // jeśli i będzie == 0, warunek stanie się fałszem
cin >> temp;
if (temp % 2 == 1) ilenp++;
else ilep++;
}
cout << "Nieparzystych " << ilenp << "\n";
cout << "Parzystych " << ilep << "\n";
}
Zadanie #1.7
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
char znak;
unsigned ile = 0;
do {
cout << "Podaj znak:";
cin >> znak;
ile++;
} while (znak != 'x');
cout << "Pobrano " << ile << " znaków.\n";
}
Zadanie #1.8
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
float a, b;
char znak;
cout << "Podaj dwie liczby: ";
cin >> a >> b;
cout << "Podaj znak: ";
cin >> znak;
if (znak == '+') {
cout << a << znak << b << "=" << a + b << endl;
}
else if (znak == '-') {
cout << a << znak << b << "=" << a - b << endl;
if (a - b != b - a)
cout << b << znak << a << "=" << b - a << endl;
}
else if (znak == '*') {
cout << a << znak << b << "=" << a * b << endl;
}
else if (znak == '/') {
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 49
if (a != 0.0) {
cout << b << znak << a << "=" << b / a << endl;
}
if (b != 0.0 and a!=b) {
cout << a << znak << b << "=" << a / b << endl;
}
}
else {
cout << "Coś nie tak, znak nierozpoznany.\n";
}
}
Zadanie #1.9
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
int x;
cin >> x;
if (x < 0) x--;
else if (x > 0) x++;
cout << x << endl;
if (x % 2 == 0) cout << "tak";
else cout << "nie";
}
Zadanie #1.10
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
// 1. sposób
for (int i = 1; i <= 100; i++) cout << i << " "; // zmienna i żyje tylko w pętli for,
// nie istnieje poza nią
cout << endl;
// 2. sposób
for (int i = 100; i--;) cout << 100 - i << " ";
cout << endl;
// 3. sposób
for (int i = 0; 100 - i++; ) cout << i << " ";
cout << endl;
// 4. sposób
int i = 1; // teraz zmienna i żyje w programie (poza pętlami)
while (i <= 100) cout << i++ << " ";
cout << endl;
// 5. sposób
i = 1;
do {
cout << i++ << " ";
} while (i<=100);
cout << endl;
}
26589ec988c76404b19a97e88c6609a5
2
50 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #1.11
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
for (int i = 100; i >= 10; i--) {
if (i % 7 != 0) cout << i << " ";
}
}
Zadanie #1.12
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
for (int i = -25; i <= 25; i++) {
if (i != 0) cout << i << " ";
}
}
Zadanie #1.13
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
int ile = 0;
for (int i = 1; i <= 120; i++) {
if (i % 5 == 0 and i % 11 == 0) continue;
cout << i << " ";
ile++;
}
cout << "\n\nLiczb wyświetlonych: " << ile << endl;
cout << "\n\nLiczb pominiętych: " << 120 - ile << endl;
}
Zadanie #1.14
#include <iostream>
#include <vector>
using namespace std;
int main() {
setlocale(LC_ALL, "");
// wzór to cyklicznie powtarzający się ciąg 3, 1, 2, 1 itd.
vector<int> cykl = { 3,1,2,1 };
size_t elementy = 1;
while (elementy <= 100) {
cout << cykl[(elementy++ - 1) % 4] << " ";
// cykl[0], cykl[1], cykl[2], cykl[3], cykl[0] i tak 100 razy
}
}
/* Uwaga! Jak interpretować część (elementy++ - 1)?
Komputer spróbuje obliczyć różnicę (elementy++) - (1).
W tym celu musi obliczyć wartość po lewej i prawej stronie znaku odejmowania.
Wyrażenie elementy++ najpierw zwraca wartość elementy.
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 51
Zadanie #1.15
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
// 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, ...
// wzór to kolejne liczby od 1, wyświetlane tyle razy, ile wynosi ta liczba. Zatem kolejny element to
// pięć piątek... potem sześć szóstek itd.
int n = 1, temp = 0;
int ile = 1;
while (ile <= 100) {
// najpierw temp porównany jest z n, potem temp rośnie o jeden
if (temp++ < n) {
cout << n << " ";
ile++;
}
else {
temp = 0;
n++;
}
}
/*
1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10
10 10 10 10 11 11 11 11 11 11 11 11 11 11 11 12 12 12 12 12 12 12 12 12 12 12 12 13 13 13 13 13
13 13 13 13 13 13 13 13 14 14 14 14 14 14 14 14 14
*/
}
Zadanie #1.16
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
// 100, 99, 97, 94, 90, 85, ...
// Kolejne liczby są mniejsze o liczbę rosnącą o jeden.
// Zatem następne będzie 85-6, czyli 79, potem 79-7 itd.
int ile = 1;
int n = 100;
while (ile <= 100) {
cout << n << " ";
n -= ile++;
}
26589ec988c76404b19a97e88c6609a5
2
52 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
/*
100 99 97 94 90 85 79 72 64 55 45 34 22 9 -5 -20 -36 -53 -71 -90 -110 -131 -153 -176 -200 -225 -251
-278 -306 -335 -365 -396 -428 -461 -495 -530 -566 -603 -641 -680 -720 -761 -803 -846 -890 -935 -981
-1028 -1076 -1125 -1175 -1226 -1278 -1331 -1385 -1440 -1496 -1553 -1611 -1670 -1730 -1791 -1853
-1916 -1980 -2045 -2111 -2178 -2246 -2315 -2385 -2456 -2528 -2601 -2675 -2750 -2826 -2903 -2981
-3060 -3140 -3221 -3303 -3386 -3470 -3555 -3641 -3728 -3816 -3905 -3995 -4086 -4178 -4271 -4365
-4460 -4556 -4653 -4751 -4850
*/
}
Zadanie #1.17
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
// 6, 2, 8, 3, 10, 4, 12, 5, 14, 6, ...
// Kolejne wyrazy ciągu to 16 i 7. Mamy tu jakby dwa ciągi przemieszane. Jeden to parzyste liczby
// zaczynające się od 6, a drugi to kolejne liczby zaczynające się od 2. Oba ciągi przeplatają się...
int a = 6, b = 2;
for (int i = 1; i <= 100; i++) {
if (i % 2 == 1) { // ciąg a
cout << a << ", ";
a += 2;
}
else { // ciąg b
cout << b++ << ", ";
}
}
}
/*
6, 2, 8, 3, 10, 4, 12, 5, 14, 6, 16, 7, 18, 8, 20, 9, 22, 10, 24, 11, 26, 12, 28, 13, 30, 14, 32, 15, 34, 16, 36, 17,
38, 18, 40, 19, 42, 20, 44, 21, 46, 22, 48, 23, 50, 24, 52, 25, 54, 26, 56, 27, 58, 28, 60, 29, 62, 30, 64, 31,
66, 32, 68, 33, 70, 34, 72, 35, 74, 36, 76, 37, 78, 38, 80, 39, 82, 40, 84, 41, 86, 42, 88, 43, 90, 44, 92, 45,
94, 46, 96, 47, 98, 48, 100, 49, 102, 50, 104, 51
*/
Zadanie #1.18
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
int pobrana;
do {
cout << "Podaj liczbę:";
cin >> pobrana;
cout << 2 * pobrana << "\n";
} while (pobrana < 1 or pobrana > 10);
}
Zadanie #1.19
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
// wersja naiwna (więcej kroków, if w pętli)
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 53
Zadanie #1.20
#include <iostream>
#include <vector>
using namespace std;
int main() {
setlocale(LC_ALL, "");
Zadanie #1.21
Przykładowe rozwiązanie 1.
#include <iostream>
#include <vector>
using namespace std;
int main() {
setlocale(LC_ALL, "");
vector<int> v;
int temp;
for (int i = 5; i--;) {
cin >> temp;
v.push_back(temp);
cout << temp << " ";
}
// test na ciąg rosnący (każda kolejna liczba musi być większa)
bool jest = true;
for (size_t pozycja = 0; pozycja < v.size() - 1; pozycja++) {
if (v[pozycja] >= v[pozycja + 1]) {
jest = false;
break;
}
}
if (jest) cout << "Ciąg jest rosnący.";
}
26589ec988c76404b19a97e88c6609a5
2
54 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Przykładowe rozwiązanie 2.
#include <iostream>
using namespace std;
int main() {
setlocale(LC_ALL, "");
int poprzednia;
int obecna;
bool rosnacy = true;
Zadanie #1.22
#include <iostream>
#include <vector>
using namespace std;
int main() {
setlocale(LC_ALL, "");
vector<int> v;
int pomoc;
while (true) {
cout << ": ";
cin >> pomoc;
v.push_back(pomoc);
if (v.size() >= 2 && v.back() == v[v.size() - 2]) break; // porównanie dwóch
// ostatnich elementów
}
}
Zadanie #1.23
#include <iostream>
#include <vector>
using namespace std;
int main() {
setlocale(LC_ALL, "");
vector<int> v;
int pomoc;
while (v.size() < 10) {
cout << ": ";
cin >> pomoc;
bool istnieje = false;
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 55
for (auto e : v)
if (pomoc == e) {
istnieje = true;
break;
}
if (!istnieje) v.push_back(pomoc);
cout << "liczba elementów w wektorze: " << v.size() << "\n";
}
cout << "ilość=" << v.size() << endl;
for (auto e : v) cout << e << " "; // podgląd wektora
}
Zadanie #1.24
#include <iostream>
#include <vector>
using namespace std;
int main() {
setlocale(LC_ALL, "");
vector<char> samogloski = { 'e','y','u','i','o','a' };
vector<char> znaki;
char pomoc;
do {
cout << ": ";
cin >> pomoc;
// test na samogłoskę
bool jest = false;
for (char e : samogloski) if (e == pomoc) {
jest = true;
break;
}
if (jest)
znaki.insert(znaki.begin(), pomoc); // dodaj na początek
else if (pomoc == '*' and znaki.size())
znaki.erase(znaki.begin()); // usuwam pierwszy
else if (pomoc == '#' and znaki.size())
znaki.pop_back(); // wyrzucam z końca
else znaki.push_back(pomoc); // dodaj na koniec
// za każdym razem prezentuj zawartość wektora w celu monitorowania operacji
for (auto e : znaki) cout << e;
cout << endl;
} while (pomoc != '!');
}
/* Ciekawostka: W przypadku kontenerów vector<> usuwanie i dodawanie na końcu wektora jest
wydajne.
Operacje usuwania/dodawania w środku lub na początku wymagają przenoszenia
kontenera w pamięci w nowe miejsce. Jednak dla potrzeb edukacji i przy tak
malutkich programach kwestie optymalizacji możemy świadomie pomijać. */
Zadanie #1.25
#include <iostream>
#include <vector>
using namespace std;
int main() {
setlocale(LC_ALL, "");
26589ec988c76404b19a97e88c6609a5
2
56 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
vector<float> liczby;
float a, b;
do {
cout << "Podaj liczbę: ";
cin >> a;
cout << "Podaj liczbę: ";
cin >> b;
liczby.push_back(a);
liczby.push_back(b);
if (a * b <= 1000.0) liczby.push_back(a * b);
// oglądam zawartość dla prezentacji
for (auto e : liczby) cout << e << " ";
cout << endl;
} while (a * b <= 1000);
}
Zadanie #1.26
#include <iostream>
#include <vector>
using namespace std;
int main() {
setlocale(LC_ALL, "");
vector<int> v = { 1,2,4,3,6,8,7,7,8,3,4,5,6,7,1,3,9,1,0,4,2,3,6,9 };
// a
for (size_t i = 0; i < v.size() - 2; i++) {
if (v[i] <= v[i + 1] and v[i + 1] <= v[i + 2]) // niemalejąca trójka liczb w wektorze?
cout << v[i] << " " << v[i + 1] << " " << v[i + 2] << endl;
}
// b
int start = 0, pozm = 0, dl = 1, dlm = 0; // pozm: pozycja maksymalnego ciągu, dlm:
// długość maksymalnego ciągu
for (size_t poz = 0; poz < v.size() - 1; poz++) {
if (v[poz] <= v[poz + 1]) { // porządek zachowany
if (dl == 1) start = poz; // pierwszy porządek po nieporządku
dl++; // długość obecnego znalezionego porządku
if (dlm < dl) { // jeżeli obecna długość jest większa niż dotychczasowa maksymalna,
// zapamiętuję ją
dlm = dl;
pozm = start;
}
}
else dl = 1; // brak porządku, zaczynamy od nowa numerowanie (nowa pozycja startowa,
// nowa długość)
}
cout << "Najdłuższy podciąg ";
for (int i = pozm; i < pozm + dlm; i++) cout << v[i] << ",";
cout << " zaczyna się na pozycji " << pozm << " i ma długość " << dlm << endl;
// c
// zauważ, że największą liczbą w wektorze jest 9, najmniejszą 0. Wykorzystamy to!
vector<int> liczniki;
liczniki.resize(10, 0); // 10 elementów o pozycji 0-9, z wartościami 0
cout << endl;
for (auto e : liczniki) cout << e << ","; // wszędzie wartości 0
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 57
// prezentacja zliczenia
for (int poz = 0; poz < liczniki.size(); poz++) {
cout << "Liczba " << poz << " wystąpień: " << liczniki[poz] << endl;
}
cout << "\n\n";
}
Zadanie #1.27
#include <iostream>
#include <vector>
using namespace std;
int main() {
setlocale(LC_ALL, "");
vector<int> v1 = { 1,3,5,7,9 };
vector<int> v2 = { 1,4,7,11,15 };
vector<int> v3 = { 1,2,3,4,5,6,7,8,9,20 };
// a
cout << "v1 część wspólna z v2 = ";
for (auto e1 : v1) {
for (auto e2 : v2) {
if (e1 == e2) cout << e1 << " ";
}
}
cout << "\n\n";
// b
vector<int> v12{}; // wektor z sumą v1+v2
v12.insert(v12.begin(), v1.begin(), v1.end()); // v12 zawiera wszystko z v1
vector<int> v312; // wektor z różnicą v3-(v1+v2)
// dodam elementy z v2 do v12 (ze sprawdzeniem, czy ich tam już nie ma)
for (auto dodaj : v2) {
bool jest = false;
for (auto e : v12) {
if (e == dodaj) {
jest = true; // element już jest, nie dodam go
break;
}
}
if (!jest) v12.push_back(dodaj); // nie ma, więc dodaję
}
cout << "v3 - v1+v2 = ";
for (auto e : v3) {
bool jest = false;
for (auto f : v12) {
if (e == f) {
jest = true;
break;
}
}
if (!jest) v312.push_back(e);
26589ec988c76404b19a97e88c6609a5
2
58 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
}
for (auto e : v312) cout << e << " ";
cout << "\n\n";
// c
vector<int> v123 = v12; // v123 będzie sumą v12 i v3, gdzie v12 był sumą v1 i v2
cout << "v1+v2+v3 = ";
for (auto dodaj : v3) {
bool jest = false;
for (auto e : v123) {
if (e == dodaj) {
jest = true;
break;
}
}
if (!jest) v123.push_back(dodaj); // nie ma, więc dodaję
}
for (auto e : v123) cout << e << " ";
cout << endl;
// c, wersja po cwaniacku
// można zauważyć, że v3-(v1+v2) daje liczby, które po dodaniu do v12 dadzą odpowiedź :)
vector<int> suma = v12;
// na koniec wektora suma() doklejam zawartość v312
suma.insert(suma.end(), v312.begin(), v312.end());
cout << "v1+v2+v3 = ";
for (auto e : suma) cout << e << " ";
}
Zadanie #1.28
#include <iostream>
#include <vector>
using namespace std;
int main() {
setlocale(LC_ALL, "");
vector<char> cyfry;
char znak;
do {
cout << ": ";
cin >> znak;
// skorzystaj z faktu, że char jest łatwo konwertowalny na int, gdzie '0' ma kod 48 itd.
if (znak >= 48 and znak <= 48 + 9) {
cyfry.push_back(znak);
cout << "dodałem " << znak - 48 << "\n";
}
else {
cout << "ignoruję znak\n";
}
} while (cyfry.size() < 5);
long long int x = 0;
for (int poz = cyfry.size() - 1, podstawa = 1; poz >= 0; poz--, podstawa *= 10) {
x += (cyfry[poz] - 48) * podstawa;
}
cout << "Liczba to: " << x << endl;
}
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 59
Zadanie #1.29
#include <iostream>
#include <vector>
using namespace std;
int main() {
setlocale(LC_ALL, "");
vector<bool> dane = {
1,1,0,1,0,0,0,0,0,1,1,1,1,1,0,1,0,0,1,0,1,1,0,0,0,1,1,0,0,1,1,1,0,0,1,0,0,0,0,0,1,1,
0,0,0,1,1,1,1,1,0,0,0,1,1,0,1,0,1,0,0,0,1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,0,0,1,0,0,1,1,
1,0,1,0,0,1,1,0,1,0,0,1,1,0,1,1,1,0,0,0,0,1,0,0,0,1,1,0,1,0,1,1,0,1,0,1,1,1,1,1,1,0,
0,1,0,0,1,1,1,0,0,1,0,0,1,1,0,1,0,0,1,1,0,0,1,0,1,0,1,1,0,1,1,0,0,1,1,0,0,1,0,0,1,0,
0,0,0,1,0,1,0,1,0,0,1,0,1,1,0,0,1,0,0,0,1,0,0,1,1,0,1,0,1,0,1,0,1,0,1,1,0,1,1,1,0,0,
1,1,0,0,1,0,0,1,0,1,1,1,1,1,0,1,1,1,1,1,0,1,0,0,1,1,1,1,1,1,1,0,1,0,1,0,0,0,1,1,0,0,
0,1,0,0,0,0,1,1,0,1,0,1,1,0,0,0,1,1,1,1,0,1,0,0,1,0,1,1,0,0,1,0,0,0,1,0,0,0,0,0,1,1,
0,1,1,1,1,0,1,0,0,1,1,1,1,0,0,0,1,0,0,1,0,1,1,1,1,0,0,1,1,1,0,0,0,1,1,1,1,0,0,1,0,0,
0,1,1,1,1,0,0,0,1,1,0,1,0,1,0,0,1,1,1,1,1,0,1,0,1,1,1,1,1 };
// 1 i 0 są łatwo konwertowalne na true i false
cout << "Liczba dni: " << dane.size() << endl;
// a
int sukces_dni = 0;
for (bool dzien : dane) {
if (dzien) sukces_dni++;
}
cout << "W czasie " << dane.size() << " dni Kasia odniosła sukces " << sukces_dni <<
´" razy.\n\n";
// b
int okresy5 = 0; // odpowiedź
int czas = 0; // pomocnicza zmienna
vector<int> poczatki; // początkowe dni okresów porażek trwających minimum 5 dni
int dzien = 1;
for (bool sukces : dane) {
if (!sukces) { // jeżeli true
czas++;
}
else {
if (czas >= 5) {
okresy5++;
poczatki.push_back(dzien - czas);
}
czas = 0;
}
dzien++;
}
cout << "Okresów trwających przynajmniej 5 dni bez właściwej diety było: "
´<< okresy5 << endl;
cout << "Początkowe dni okresów to: ";
for (auto start : poczatki) cout << start << " ";
}
Zadanie #1.30
#include <iostream>
#include <vector>
using namespace std;
26589ec988c76404b19a97e88c6609a5
2
60 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
int main() {
setlocale(LC_ALL, "");
long long int waga = 1;
int okrazenia = 13;
vector<int> okrazenia_waga;
okrazenia_waga.resize(okrazenia); // gromadzimy wagę po kolejnych okrążeniach
okrazenia_waga[0] = 1; // pierwsze okrążenie (liczymy od 0)
okrazenia_waga[1] = 1; // drugie okrążenie
for (int okr = 2; okr < okrazenia; okr++) {
// suma wag ostatnich dwóch okrążeń
okrazenia_waga[okr] = okrazenia_waga[okr - 1] + okrazenia_waga[okr - 2];
}
cout << "Po okrążeniu = " << okrazenia << " waga bloba to " << okrazenia_waga
´[okrazenia - 1] << endl;
cout << "A oto historia wagi w kolejnych okrążeniach:";
for (auto waga : okrazenia_waga) cout << waga << " ";
}
Zadanie #1.31
Rozwiązanie a)
Dwa razy wyświetli się 1. Za pierwszym razem najpierw a jest inkrementowane
(++a), dopiero potem trafia do strumienia wyjściowego. Za drugim razem a jako
wartość 1 bezpośrednio trafia do strumienia.
Rozwiązanie b)
Wyświetli się 0. Prawostronny operator inkrementacji ++ ma mniejszy priorytet
niż odejmowanie, dlatego najpierw obliczona zostanie wartość a–1, czyli będzie
to 0 (bo a to wciąż 1). Następnie wykonane zostanie porównanie 0&&1, które
oczywiście daje wartość false, co przy wyświetlaniu pokaże 0. Pod koniec inkre-
mentacja zwiększy a do wartości 2 i to ona wyświetli się w drugiej linijce kodu.
Rozwiązanie c)
Siedem (1+6–0=7). Kolejność działań jest jak na matematyce, jednak wynik dzie-
lenia literałów całkowitych 4/5 jest konwertowany na liczbę całkowitą poprzez
redukcję części ułamkowej. Zatem 4/5, choć wynosi 0.8, to po odcięciu części po
przecinku (redukcja do typu całkowitego, bo takiego typu są literały 4 oraz 5)
jest to po prostu 0.
Rozwiązanie d)
Operator and ma mniejszy priorytet niż operator <<, w efekcie komputer pró-
buje wykonać jakby operację: (cout << true) and (false << endl), co jest —
nie oszukujmy się — absurdalne ! Nie da się logicznie za pomocą koniunkcji
(i) połączyć części objętych nawiasem.
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 61
Zadanie #1.32
#include <iostream>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////
int main() {
vector<int> x = { 2,7,1,1,4,9,3,2,1,4,1,9,6,1,3,0,1,2,3,6,8,5,6,9,
3,0,8,1,8,8,7,0,7,8,5,0,2,2,3,7,1,7,2,4,7,7,5,9,0,7,7,9,2,2,2,7,
0,0,5,4,6,3,9,3,5,1,0,0,9,2,9,2,8,5,0,8,5,7,0,9,6,4,9,7,8,8,6,5,
4,3,2,5,8,9,4,6,8,7,9,9 };
int odl = -1;
for (size_t poz = 0; poz < x.size(); poz++) {
if (x[poz] == 9) {
if (odl != -1) {
cout << odl << " ";
}
odl = 0;
}
else if (odl != -1) odl++;
}
}
Zadanie #1.33
#include <iostream>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////
int main() {
vector<int> x = { 2,7,1,1,4,9,3,2,1,4,1,9,6,1,3,0,1,2,3,6,8,5,6,9,
3,0,8,1,8,8,7,0,7,8,5,0,2,2,3,7,1,7,2,4,7,7,5,9,0,7,7,9,2,2,2,7,
0,0,5,4,6,3,9,3,5,1,0,0,9,2,9,2,8,5,0,8,5,7,0,9,6,4,9,7,8,8,6,5,
4,3,2,5,8,9,4,6,8,7,9,9 };
int ile_razy_sasiadki = 0;
int dziesiec = 0;
for (size_t poz = 0; poz < x.size() - 1; poz++) {
if (x[poz] == x[poz + 1]) {
ile_razy_sasiadki++;
cout << x[poz] << "," << x[poz + 1] << endl;
}
if (x[poz] + x[poz + 1] == 10) {
dziesiec++;
cout << x[poz] << "," << x[poz + 1] << "=10" << endl;
}
}
cout << "a) " << ile_razy_sasiadki << endl; // 11
cout << "b) " << dziesiec << endl; // 6
}
Zadanie #1.34
#include <iostream>
using namespace std;
//////////////////////////////////////////////////////
int main() {
26589ec988c76404b19a97e88c6609a5
2
62 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
setlocale(LC_ALL, "");
char znak;
int suma(0);
do {
cout << "Podaj znak:";
cin >> znak;
cout << "Wpisano znak " << znak;
if (!(znak >= 65 and znak <= 90)
and !(znak >= 97 and znak <= 122)
and !(znak >= 48 and znak <= 57)) {
cout << "Wprowadzono niedozwolony znak!\n";
continue;
}
suma += znak;
cout << ", wartość znaku: " << znak - 0;
cout << ", aktualna suma = " << suma << endl;
} while (suma <= 350);
}
Zadanie #1.35
Przykładowe rozwiązanie 1.
#include <iostream>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////
int main() {
setlocale(LC_ALL, "");
vector<int> v = { 3,2,4,3,5,4,6,5,6,8 };
while (v.size()) {
cout << v.front() << " ";
v.front() = v.back();
v.pop_back();
}
}
Przykładowe rozwiązanie 2.
#include <iostream>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////
int main() {
setlocale(LC_ALL, "");
vector<int> v = { 3,2,4,3,5,4,6,5,6,8 };
auto iter = v.begin();
while (iter != v.end()) cout << *iter++ << " "; // czary :)
// iter++ przesuwa wskaźnik (iterator) na kolejny element,
// a operator * pobiera wartość, na którą wskazuje iterator.
// Całość trwa, dopóki iterator nie wskoczy za ostatni element wektora
}
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 63
Zadanie #1.36
#include <iostream>
using namespace std;
//////////////////////////////////////////////////////
int main() {
setlocale(LC_ALL, "");
float a = 5, b = 4, c = 3; // trójkąt egipski o bokach 3, 4, 5 działa :)
// sugestia: sprawdź wyniki dla boków: a=10, b=10, c=sqrt(200) oraz dla a=4, b=3, c=2.
// Pierwszy przypadek tworzy trójkąt prostokątny, drugi nie
bool sukces = false;
// przetestuję trzy możliwe przypadki boków
if (a * a + b * b == c * c) sukces = true;
else if (a * a + c * c == b * b) sukces = true;
else if (b * b + c * c == a * a) sukces = true;
if (sukces) cout << "No i mamy możliwość zbudowania trójkąta prostokątnego.\n";
else cout << "Nie da rady zbudować trójkąta prostokątnego.\n";
}
Zadanie #1.37
#include <iostream>
using namespace std;
//////////////////////////////////////////////////////
int main() {
setlocale(LC_ALL, "");
float a, b;
a = 10.2;
b = 11.7;
cout << "Powinniśmy otrzymać " << a * b << ", jednak bez korzystania ze znaku *\n";
cout << "Bez * = " << a / (1. / b) << endl;
float A = 10.25;
int B = 12;
cout << "Powinniśmy otrzymać " << A * B << ", jednak bez korzystania ze znaku * i / \n";
float suma = 0.; // 0. to to samo co 0.0
while (B > 0) {
suma += A;
B -= 1;
}
cout << "Bez * / = " << suma << endl;
}
Zadanie #1.38
#include <iostream>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////
int main() {
setlocale(LC_ALL, "");
vector<int> v = { 1,2,3,2,5,6,9,1,3,7,5,8,0,9,3,1,2,5,7,6,3,4,2,1,0,8,9,7,8,
4,6,3,2,5,4,7,8,9,1,3,2,5,4,7,5,6,8,0,1,2,3,6,5,8,7,1,1,2,3,4,4,5,5,6,8,
9,0,9,8,1,9,7,5,4,1,2,7,6,9,3,4,2,6 };
26589ec988c76404b19a97e88c6609a5
2
64 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
// Rozwiązanie 1.
for (unsigned poz = 0; poz < v.size(); poz++) {
unsigned suma = 0;
for (int dl = 0; poz + dl < v.size(); dl++) {
suma += v[poz + dl];
if (suma == 10) {
cout << "PODCIĄG: ";
for (unsigned i = poz; i <= poz + dl; i++) cout << v[i] << " ";
cout << "POZYCJE: ";
for (unsigned i = poz; i <= poz + dl; i++) cout << i << " ";
cout << endl;
}
else if (suma > 10) break;
}
}
cout << "\n\n";
// Rozwiązanie 2.
int N = v.size();
for (int dlugosc_podciagu = N; dlugosc_podciagu >= 1; dlugosc_podciagu--) {
for (int start = 0; start + dlugosc_podciagu <= N; start++) {
unsigned koniec = start + dlugosc_podciagu - 1;
unsigned suma = 0;
for (unsigned x = start; x <= koniec; x++) {
suma += v[x];
if (suma > 10) break;
}
if (suma == 10) {
cout << "PODCIĄG: ";
for (unsigned x = start; x <= koniec; x++) cout << v[x] << " ";
cout << "POZYCJE: ";
for (unsigned x = start; x <= koniec; x++) cout << x << " ";
cout << endl;
}
}
}
}
Zadanie #1.39
#include <iostream>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////
int main() {
setlocale(LC_ALL, "");
vector<char> znaki = { 'x','P','Q','4','\n','%','u','@','e',
'T','B','$', '!',':','"','1','<','d','k','L','$',')','$','B','x',
'w','q','P','c','X','B','>','?','[','r','x','$','#','}','|','d','l','n','b','V','!' };
unsigned suma_znakow = 0;
for (auto e : znaki) if (e >= 48 and e <= 48 + 9) suma_znakow += e - 48;
cout << "Suma znaków: " << suma_znakow << endl;
// usuwam znaki, które są na początku i na końcu, aby ich nie wyświetlać
char s = znaki.front();
char k = znaki.back();
for (int poz = 0; poz < znaki.size(); poz++) {
if (znaki[poz] == s or znaki[poz] == k) {
znaki.erase(znaki.begin() + poz);
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 65
poz--;
continue;
}
}
// rozpoczynam poszukiwania powtarzających się znaków, które nie leżały na początku
// i końcu wektora
for (int poz = 0; poz < znaki.size(); poz++) {
bool dublet = false;
for (int spr = poz + 1; spr < znaki.size(); spr++) {
if (znaki[poz] == znaki[spr]) { // jest powtórka
dublet = true;
// teraz usuwam powtórzenia, by ponownie nie wyświetlić powtórki
znaki.erase(znaki.begin() + spr);
spr--;
}
}
if (dublet) {
cout << znaki[poz] << endl;
}
}
}
Zadanie #1.40
Jak się spało?
Część 2.
(#2) Pierwotniaczki
Zadanie #2.1
#include <iostream>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////
string zad1(string imie) {
string samogloski = "eyuioaEYUIOA";
int ilerazy = 0;
for (auto literka : imie) {
if (samogloski.find(literka) != string::npos) ilerazy++;
}
string wynik("");
while (ilerazy--) wynik += imie + " ";
return wynik;
}
int main() {
setlocale(LC_ALL, "");
vector<string> imiona={ "Toudi", "Barnaba", "Pantofelek", "Max"}; // test dla kilku imion
while (imiona.size()) {
cout << imiona.back() << ":" << endl;
cout << zad1(imiona.back()) << endl;
imiona.pop_back();
}
}
26589ec988c76404b19a97e88c6609a5
2
66 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #2.2
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////
int zad2(vector<int>& v) {
int maks = v[0];
int poz = -1;
for (int i = 0; i < v.size(); i++) {
if (v[i] >= maks) {
maks = v[i];
poz = i;
}
}
v.erase(v.begin() + poz);
return maks;
}
int suma(vector<int> v) {
int suma = 0;
for (auto e : v) suma += e;
return suma;
}
int main() {
setlocale(LC_ALL, "");
srand(time(0)); // bez tego losowanie z wykorzystaniem funkcji rand() zawsze zwróci ten sam
// wynik
vector<int> v;
for (int i = 3; i--;) {
v.push_back(rand() % 20 + 1); // [dowolna liczba z zakresu 1-20]
cout << v.back() << " ";
}
cout << endl;
int maks = zad2(v);
int s = suma(v);
while (maks--) cout << s << " ";
}
Zadanie #2.3
#include <iostream>
#include <ctime>
using namespace std;
//////////////////////////////////////////////////////
string wylosowany_napis() {
// angielskie
string litery = "qazwsxedcrfvtgbyhnujmikolpQAZWSXEDCRFVTGBYHNUJMIKOLP";
char znak;
int ile = 0;
string wynik;
do {
znak = litery[rand() % litery.size()]; // losuję pozycję w napisie
wynik += znak;
ile++;
} while (znak != 'z' and znak != 'A');
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 67
Zadanie #2.4
Przykładowe rozwiązanie 1.
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////
vector<int> vector_generator(int ile = 10, int start = 0, int koniec = 20) {
// gdy do argumentu przypiszesz wartość, będzie ona domyślna
vector<int> v;
for (int i = 1; i <= ile; i++) {
int losowa = rand() % (koniec - start + 1) + start;
int pozycja = (v.size()) ? rand() % v.size() : 0;
v.insert(v.begin() + pozycja, losowa); // nie nadpisze, przesunie
}
return v;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
for (auto e : vector_generator(20)) cout << e << " ";
}
Przykładowe rozwiązanie 2.
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////
int wylosuj_liczbe(int poczatek, int koniec) {
return rand() % (koniec - poczatek + 1) + poczatek;
}
int main() {
setlocale(LC_ALL, "");
srand(time(0));
26589ec988c76404b19a97e88c6609a5
2
68 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
liczby[indeks] = wylosowana;
zajete_indeksy[indeks] = true;
}
Zadanie #2.5
#include <iostream>
#include <ctime>
using namespace std;
//////////////////////////////////////////////////////
void zad5() {
unsigned ile = 0;
while (true) {
int x = rand() % 101;
cout << x << " ";
if (x != 100) ile++;
else break;
}
cout << "\nIle = " << ile << " nie licząc 100." << endl;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
zad5();
}
Zadanie #2.6
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////
void zad6() {
vector<int> v;
// uważaj, może wypaść 0 nieznaną ilość razy
unsigned uj = 0;
unsigned dod = 0;
unsigned parz = 0;
for (int i = 10; i--;) {
v.push_back(rand() % 21 - 10); // [-10:10]
if (v.back() < 0) uj++;
if (v.back() > 0) dod++;
if (v.back() % 2 == 0) parz++;
}
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 69
cout << "Uj=" << uj << " Dod=" << dod << " Parz=" << parz
<< " Nieparz=" << 10 - parz << endl;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
zad6();
}
Zadanie #2.7
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////
int szukajMaksa(vector<int>& v) {
int maks = v[0];
int ost_p(0);
for (int poz = 0; poz < v.size(); poz++) {
if (maks < v[poz]) {
maks = v[poz];
ost_p = poz;
}
}
v[ost_p] = -1; // gwarancja, że już tej liczby nie uznam za maksymalną
return maks;
}
void zad7() {
vector<int> v;
for (int i = 20; i--;) {
v.push_back(rand() % 1001); // 0-1000
cout << v.back() << " ";
}
cout << v.size() << endl;
cout << "\n\n";
for (int trzy = 3; trzy--;) {
cout << szukajMaksa(v) << endl;
}
}
int main() {
setlocale(LC_ALL, "");
srand(time(0));
zad7();
}
Zadanie #2.8
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <iomanip>
using namespace std;
//////////////////////////////////////////////////////
double double_01_Generator_simple() { // wersja 1., sztywna
26589ec988c76404b19a97e88c6609a5
2
70 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
int main() {
setlocale(LC_ALL, ""); srand(time(0));
// wszystkie funkcje zwracają liczbę [0,1] z różną dokładnością po przecinku
cout << fixed; // będzie tyle miejsc po przecinku, ile setprecision "powie"
cout << setprecision(3) << double_01_Generator_simple() << endl << endl;
// zawsze 3 miejsca po przecinku
cout << setprecision(3) << double_01_Generator_v1(3) << endl;
// 3 miejsca po przecinku
cout << setprecision(5) << double_01_Generator_v1(5) << endl;
// 5 miejsc po przecinku
cout << setprecision(2) << double_01_Generator_v2(2) << endl;
// 2 miejsca po przecinku
cout << setprecision(6) << double_01_Generator_v2(6) << endl;
// 6 miejsc po przecinku
}
Zadanie #2.9
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <iomanip>
using namespace std;
//////////////////////////////////////////////////////
double double_simple_Generator() { // wersja nieuniwersalna [-1.000:1.000]
return (rand() % 2001 - 1000) / 1000.0;
}
// double_Generator, wersja uniwersalna. Pozwala wygenerować
// liczbę z zakresu [a;b] o podanej precyzji liczb po przecinku,
// funkcja pow() z biblioteki <cmath> : pow(a,b) = a do potęgi b
double double_Generator(int start, int koniec, int poprzecinku = 3) {
long long d = pow(10, poprzecinku);
long long x = rand() % (koniec * d - start * d + 1) + start * d;
return x / (d * 1.0);
}
vector<double> zad9() {
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 71
vector<double> v;
double suma = 0.0;
for (int i = 20; i--;) {
v.push_back(double_simple_Generator()); // 20 losowych
suma += v.back();
}
cout << "Średnia = " << suma / 20.0 << "\n\n";
return v; // zwróć wylosowany wektor
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
Zadanie #2.10
#include <iostream>
#include <ctime>
using namespace std;
//////////////////////////////////////////////////////
pair<int,char> zad10() {
int temp, L = rand() % 11 + 20;
temp = L;
cout << "L=" << L << endl << ":";
char Z;
cin >> Z;
while (temp--) cout << Z;
cout << endl;
return { L, Z };
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
auto p = zad10();
// zerknij na to ;)
cout << string(p.first,p.second) << endl;
}
Zadanie #2.11
#include <iostream>
using namespace std;
//////////////////////////////////////////////////////
bool jestParzysta(unsigned x) {
return !(x & 1);
}
int main() {
cout << jestParzysta(10) << endl;
cout << jestParzysta(13) << endl;
}
26589ec988c76404b19a97e88c6609a5
2
72 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #2.12
#include <iostream>
#include <iomanip>
using namespace std;
//////////////////////////////////////////////////////
double zlep(long long int a, long long int b) {
// wartość bezwzględna to funkcja abs() z biblioteki <cmath>,
// ale można zrobić szybką operację:
if (b < 0) b = -b; // zamiast abs()
long long int temp = b;
double d = 10;
while (temp / 10) {
d *= 10;
temp /= 10;
}
return a + b / d;
}
void zad12() {
int a, b;
cout << "Podaj a b:";
cin >> a >> b;
cout << setprecision(15) << zlep(a, b) << endl;
}
int main() {
setlocale(LC_ALL, "");
zad12();
}
Zadanie #2.13
#include <iostream>
#include <ctime>
using namespace std;
//////////////////////////////////////////////////////
void rysuj(char znak, int wiersze, int kolumny) {
while (wiersze--) {
for (int i = 1; i <= kolumny; i++)
cout << znak;
cout << endl;
}
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
char znak;
int a, b;
cout << "Znak: ";
cin >> znak;
a = rand() % 6 + 5;
b = rand() % 6 + 5;
rysuj(znak, a, b);
}
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 73
Zadanie #2.14
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////
vector<int> losowanko() {
vector<int> v;
int losowa, od = 1;
do {
losowa = rand() % (1000 - od + 1) + od;
cout << "losowa=" << losowa << endl;
od = losowa;
v.push_back(losowa);
} while (losowa < 1000);
return v;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
for (auto e : losowanko()) cout << e << " ";
}
Zadanie #2.15
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////
void zad15() {
vector<int> v;
int ile = rand() % 91 + 10; // losowa ilość
while (ile--) v.push_back(rand() % 100 + 1); // generuję wektor
cout << "Przed: ";
for (int i = v.size() - 1; i >= 0; i--) cout << v[i] << " ";
cout << endl;
for (auto& e : v) {
if (e & 1) e = -e;
else e = 0;
}
cout << "Po: ";
for (int i = v.size() - 1; i >= 0; i--) cout << v[i] << " ";
cout << "\n\n";
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
zad15();
}
Zadanie #2.16
#include <iostream>
#include <ctime>
using namespace std;
//////////////////////////////////////////////////////
26589ec988c76404b19a97e88c6609a5
2
74 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #2.17
#include <iostream>
#include <ctime>
using namespace std;
//////////////////////////////////////////////////////
void szachownica(char znak, int n) {
for (int w = 1; w <= n; w++) {
for (int k = 1; k <= n; k++)
// gdy w oraz k są równocześnie parzyste lub nieparzyste, pokaż znak; jeśli nie, to spacje
if ((w & 1 and k & 1) or (!(w & 1) and !(k & 1))) cout << znak;
else cout << ' ';
cout << endl;
}
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
szachownica('#', rand() % 8 + 5);
cout << "\n";
szachownica('$', 12);
}
Zadanie #2.18
#include <iostream>
#include <ctime>
using namespace std;
//////////////////////////////////////////////////////
void kwadrat_pusty(char znak, int n) {
for (int w = 1; w <= n; w++) {
for (int k = 1; k <= n; k++)
if (w == 1 or w == n or k == 1 or k == n) cout << znak;
else cout << ' ';
cout << endl;
}
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
kwadrat_pusty('#', rand() % 8 + 5);
}
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 75
Zadanie #2.19
#include <iostream>
#include <ctime>
using namespace std;
//////////////////////////////////////////////////////
void troj(char znak, int n) {
for (int w = 1; w <= n; w++) {
for (int k = 1; k <= w; k++)
cout << znak;
cout << endl;
}
}
void troj_v2(char znak, int n) {
for (int w = 1; w <= n; w++) {
cout << string(n - w, ' ');
for (int k = 1; k <= w; k++) {
cout << znak;
}
cout << endl;
}
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
int r = rand() % 8 + 5;
troj('#', r);
troj_v2('#', r);
}
Zadanie #2.20
#include <iostream>
#include <ctime>
using namespace std;
//////////////////////////////////////////////////////
void trojkat(char znak, int n) {
for (int w = 1; w <= n; w++) {
cout << string(n - w, ' ');
cout << string(2 * w - 1, znak) << endl;
}
}
void diament(char znak, int n) {
trojkat(znak, n);
for (int w = n - 1; w >= 1; w--) {
cout << string(n - w, ' ');
cout << string(2 * w - 1, znak) << endl;
}
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
int r;
do { r = rand() % 15 + 7; } while (r % 2 == 0); // aż do uzyskania nieparzystej
trojkat('#', r);
diament('#', r);
}
26589ec988c76404b19a97e88c6609a5
2
76 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #2.21
#include <iostream>
#include <ctime>
using namespace std;
//////////////////////////////////////////////////////
void kwadrat_malpa(char znak, char malpa, int n) {
// losuję pozycję znaku małpy [2;n-1][2;n-1]
int x = rand() % (n - 2) + 2;
int y = rand() % (n - 2) + 2;
for (int w = 1; w <= n; w++) { // wiersze
if (w == x) {
for (int k = 1; k <= n; k++) // kolumny
if (k == y) cout << malpa;
else cout << znak;
cout << endl;
}
else cout << string(n, znak) << endl; // cały wiersz
}
}
void kwadrat_pusty_malpa(char znak, char malpa, int n) {
int x = rand() % (n - 2) + 2;
int y = rand() % (n - 2) + 2;
for (int w = 1; w <= n; w++) { // wiersze
for (int k = 1; k <= n; k++) { // kolumny
if (k == 1 or k == n or w == 1 or w == n) cout << znak;
else if (w == x and k == y) cout << malpa;
else cout << ' ';
}
cout << endl;
}
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
kwadrat_malpa('#', '@', rand() % 8 + 5);
cout << endl;
kwadrat_pusty_malpa('#', '@', rand() % 8 + 5);
}
Zadanie #2.22
#include <iostream>
#include <ctime>
using namespace std;
//////////////////////////////////////////////////////
void trojkat(char znak, int n, int spacje_wiodace = 0) {
for (int w = 1; w <= n; w++) {
cout << string(n - w + spacje_wiodace, ' ');
cout << string(2 * w - 1, znak) << endl;
}
}
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 77
}
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
choinka('#', rand()%8+5);
}
Zadanie #2.23
Przykładowe rozwiązanie 1.
#include <iostream>
using namespace std;
//////////////////////////////////////////////////////
double potega(double x, unsigned int e) {
double wynik = 1;
for (int i = 1; i <= e; i++) {
wynik *= x;
}
return wynik;
}
double potega(double x, int e) {
if (e < 0) {
return 1 / potega(x, (unsigned)-e);
}
return potega(x, (unsigned)e);
}
int main() {
setlocale(LC_ALL, "");
cout << potega(2, 3) << endl; // 2 do potęgi trzeciej
cout << potega(2, 0) << endl; // 2 do 0
cout << potega(2, -3); // 2 do -3
}
Przykładowe rozwiązanie 2.
#include <iostream>
using namespace std;
//////////////////////////////////////////////////////
double potega(double x, unsigned int e) {
return e == 0 ? 1 : x * potega(x, e - 1);
}
double potega(double x, int e) {
if (e < 0)
return 1 / potega(x, -e);
else
return potega(x, (unsigned int)e);
}
int main() {
setlocale(LC_ALL, "");
cout << potega(2, 6) << endl;
cout << potega(2, 0) << endl;
cout << potega(2, -6) << " " << 1 / 64.0 << endl;
}
26589ec988c76404b19a97e88c6609a5
2
78 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #2.24
#include <iostream>
using namespace std;
//////////////////////////////////////////////////////
typedef long long int L;
long long int zaokr(double x) {
double reszta = x - L(x); // >=.5
if (reszta >= 0.5) return L(x) + 1;
else if (reszta <= -0.5) return L(x) - 1;
return L(x);
}
int main() {
setlocale(LC_ALL, "");
cout << zaokr(231.24123) << endl;
cout << zaokr(-231.24123) << endl;
cout << zaokr(231.94123) << endl;
cout << zaokr(-231.94123) << endl;
}
Zadanie #2.25
#include <iostream>
using namespace std;
typedef long long int L;
//////////////////////////////////////////////////////
void podwajamPoKropce(double& x) { // referencja zmieni x, bez zwracania x
L calk = x;
x = calk + (x - calk) * 2;
}
int main() {
setlocale(LC_ALL, "");
double x = 1.34;
podwajamPoKropce(x);
cout << x << endl;
x = -1.99;
podwajamPoKropce(x);
cout << x << endl;
}
Zadanie #2.26
#include <iostream>
using namespace std;
//////////////////////////////////////////////////////
double wartb(double x) {
return (x < 0) ? -x : x;
}
int main() {
cout << wartb(-5) << " " << wartb(3.14) << endl;
}
Zadanie #2.27
(treść zadania nie wymaga podawania rozwiązania)
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 79
Zadanie #2.28
#include <iostream>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////
double liniowa(double a, double b, double x) {
return a * x + b;
}
// lub np. tak
double liniowa2(vector<double>wsp, double x) {
return wsp[0] * x + wsp[1];
}
int main() {
setlocale(LC_ALL, "");
cout << liniowa(3, -4, 2.5) << endl; // 3x-4 => 3*2.5-4
cout << liniowa2({ 3,-4 }, 2.5); // przekazano wektor definiowany w locie jako {3,-4}
}
Zadanie #2.29
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
typedef long long int L;
//////////////////////////////////////////////////////
double liniowa(vector<double>wsp, double x) {
return wsp[0] * x + wsp[1];
}
void zliczaj(vector<vector<double>>& punkty) {
L na = 0, pod = 0, nad = 0;
for (auto& v : punkty) {
if (v[1] == liniowa({ 2,3 }, v[0])) // 2x+3 dla {x[0]}
na++;
else if (v[1] > liniowa({ 2,3 }, v[0]))
nad++;
else pod++;
}
cout << "Nad=" << nad << " Pod=" << pod << " Na=" << na << endl;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
vector<vector<double>> punkty; // wektor zawiera wektory
punkty.resize(100); // 100 punktów
for (auto& v : punkty) { // losuj punkt {x,y}
v.push_back((rand() % 201 - 100) / 10.0); // x
v.push_back((rand() % 201 - 100) / 10.0); // y
}
zliczaj(punkty);
// uwaga: "na" będzie najczęściej równe 0, trudno strzelić
punkty.clear();
punkty.resize(0);
punkty = { {0,1},{1,10},{2,7} };
zliczaj(punkty);
}
26589ec988c76404b19a97e88c6609a5
2
80 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #2.30
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
typedef long long int L;
//////////////////////////////////////////////////////
int main() {
setlocale(LC_ALL, ""); srand(time(0));
vector<int> v;
vector<int> ostatnie3;
int suma, pozycja = 0;
ostatnie3.resize(3, 0); // ustaw 3 elementy i przypisz im wartość 0
L ile = 0;
do {
suma = 0;
int losowa = rand() % 100 + 1;
ile++;
if (!v.size() or v.back() <= losowa) {
v.push_back(losowa);
}
cout << losowa << " ";
ostatnie3[pozycja] = losowa; // zapis ostatnich 3 elementów
pozycja = (++pozycja) % 3; // pozycja = 0,1,2,0,1,2,0,1,2,0,1,2
// obliczam sumę (muszą być minimum 3 elementy)
for (auto e : ostatnie3) {
if (e == 0) {
suma = 0;
break;
}
suma += e;
}
} while (!(suma >= 80 and suma <= 90));
cout << "\nWektor zapisanych liczb:\n";
for (auto e : v) cout << e << " ";
cout << endl;
cout << "Ile=" << ile << endl;
}
Zadanie #2.31
#include <iostream>
#include <ctime>
#include <vector>
#include <fstream>
using namespace std;
typedef long long int L;
//////////////////////////////////////////////////////
int main() {
setlocale(LC_ALL, ""); srand(time(0));
ofstream plik;
plik.open("liczby.txt");
int n;
do {
n = rand() % 1001;
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 81
if (n % 10 == 0) { // if (!n%10)
plik << n << endl;
}
} while (n != 1000);
plik.close();
}
Zadanie #2.32
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
//////////////////////////////////////////////////////
int main() {
setlocale(LC_ALL, "");
ifstream plik;
plik.open("liczby.txt"); // z zadania #2.31
int n;
vector<int> v;
while (!plik.eof()) {
// uwaga: gdy w pliku jest wiersz pusty, np. na końcu pliku, co
// jest częste w danych źródłowych do zadań maturalnych,
// można sprawdzić poprawność odczytu jak niżej
if (plik >> n) v.push_back(n);
}
plik.close();
for (auto e : v) cout << e << " ";
}
Zadanie #2.33
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
//////////////////////////////////////////////////////
int main() {
setlocale(LC_ALL, "");
// rozwiązanie nr 1, operator >>
ifstream plik;
plik.open("33_dane.txt"); // format wiersza 120;500
int n;
char znak;
vector<int> v;
while (!plik.eof()) {
if (plik >> n) // liczba do średnika
v.push_back(n);
plik >> znak; // ; średnik
if (plik >> n) // liczba po średniku
v.push_back(n);
}
plik.close();
for (auto e : v) cout << e << " ";
cout << endl << endl;
26589ec988c76404b19a97e88c6609a5
2
82 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #2.34
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
//////////////////////////////////////////////////////
int main() {
setlocale(LC_ALL, "");
ifstream plik;
plik.open("34_dane.txt");
/*
1;231;3423;dowolnie długi napis
321;345;67;inny długi napis
-351;211;0;potwornie długi napis, inny niż wszystkie
*/
string napis, pomoc;
vector<L> v;
int i = 1;
while (!plik.eof() ) {
if (i % 4 != 0) {
getline(plik, pomoc, ';');
if (pomoc.find_first_of("0123456789")!=string::npos)
v.push_back(stoll(pomoc)); // stoll: string -> long long int
}
else {
getline(plik, pomoc);
napis += pomoc;
}
i = (i + 1) % 4;
}
plik.close();
for (auto e : v) cout << e << " ";
cout << endl << napis << endl;
}
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 83
Zadanie #2.35
Rozwiązanie 1. Wykorzystuję sprawdzanie błędów: try-catch.
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
//////////////////////////////////////////////////////
bool czyDouble(string& txt) { // sprawdzam, czy txt da się zamienić na double
try {
stod(txt);
}
catch (exception e) {
return false;
}
return true;
}
int main() {
setlocale(LC_ALL, "");
setlocale(LC_NUMERIC, "C"); // przeczyta -31.21 jako double
ifstream plik;
plik.open("35_dane.txt");
string wiersz, fragment;
vector<string> napisy;
/*
1;231;3423;dowolnie długi napis;345456;inny napis
napis;321;345;67;inny długi napis;8893;krótki tekst;123123;1212;12;tekst
-31.21;napis kosmiczny;0.001;-1.0;2
*/
while (!plik.eof() and getline(plik >> std::ws, wiersz)) { // cały wiersz
// analiza wiersza od średnika do średnika
int pozp = 0, pozk = -1;
while ((pozk = wiersz.find(";", ++pozk)) != string::npos) {
fragment = wiersz.substr(pozp, pozk - pozp);
pozp = pozk + 1;
if (czyDouble(fragment)) {
cout << stod(fragment) << endl;
}
else {
napisy.push_back("#" + fragment + "#");
}
}
fragment = wiersz.substr(pozp);
if (czyDouble(fragment)) {
cout << fragment << endl;
}
else {
napisy.push_back("#" + fragment + "#");
}
}
for (auto e : napisy) cout << e << endl;
plik.close();
}
26589ec988c76404b19a97e88c6609a5
2
84 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
int main() {
setlocale(LC_ALL, "");
setlocale(LC_NUMERIC, "C"); // "12.3" -> 12.3
ifstream plik;
plik.open("35_dane.txt");
string wiersz, fragment;
vector<string> napisy;
/*
1;231;3423;dowolnie długi napis;345456;inny napis
napis;321;345;67;inny długi napis;8893;krótki tekst;123123;1212;12;tekst
-31.21;napis kosmiczny;0.001;-1.0;2
*/
while (!plik.eof() and getline(plik >> std::ws, wiersz)) {
// analiza wiersza od średnika do średnika
int pozp = 0, pozk = -1;
while ((pozk = wiersz.find(";", ++pozk)) != string::npos) {
fragment = wiersz.substr(pozp, pozk - pozp);
pozp = pozk + 1;
if (czyDouble(fragment)) {
cout << stod(fragment) << endl;
}
else {
napisy.push_back("#" + fragment + "#");
}
}
fragment = wiersz.substr(pozp);
if (czyDouble(fragment)) {
cout << fragment << endl;
}
else {
napisy.push_back("#" + fragment + "#");
}
}
for (auto e : napisy) cout << e << endl;
plik.close();
}
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 85
Zadanie #2.36
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
//////////////////////////////////////////////////////
struct A {
int a;
string b;
float c;
char d;
};
26589ec988c76404b19a97e88c6609a5
2
86 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
void dopisz(A& element, string plik, bool dopisz = true) { // dopisz na koniec pliku
ofstream p;
if (dopisz) p.open(plik, ios_base::app); // ios_base::app sprawia, że można dopisać
// do pliku
else p.open(plik); // otwieram, ale nie żeby dodać, ale by utworzyć całkiem nowy plik
p << element.a << ";" << element.b << ";" << element.c << ";" << element.d <<
´endl; // a;b;c;d w linii pliku
p.close();
// uwaga: jeżeli A.b będzie napisem zawierającym znak średnika, pomysł na zapis zostanie zepsuty;
// zakładam jednak, dla uproszczenia, że napis nie będzie zawierać średnika
}
void dopisz(vector<A>& v, string plik) { // zapisz cały wektor (przeciążenie funkcji)
ofstream p;
p.open(plik, ios_base::app); // ios_base::app sprawia, że można dopisać do pliku
for (auto& e : v)
p << e.a << ";" << e.b << ";" << e.c << ";" << e.d << endl; // a;b;c;d w linii pliku
p.close();
}
vector<A> pobierz(string plik) { // załaduj dane, zakładamy poprawność pliku
ifstream p;
p.open(plik);
vector<A> v;
while (!p.eof()) {
A element;
string pomoc;
// jeśli jest pusty wiersz na końcu, to nic nie czytam
if (!(getline(p, pomoc, ';')).good()) break;
element.a = stoi(pomoc); // int
getline(p, pomoc, ';');
element.b = pomoc; // string
getline(p, pomoc, ';');
element.c = stof(pomoc); // float
p >> element.d; // char
v.push_back(element);
}
p.close();
return v;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
// przykłady użycia funkcji (powstanie plik zad36.txt)
A a({ 1,"kaszanka",4.5,'a' }); // nowy element typu A, dane zostaną wstawione
// do a.a, a.b, a.c, a.d
dopisz(a, "zad36.txt", false); // utwórz plik od nowa, dopisz linię
a.a++;
a.b += " jest fajna";
a.c *= 2;
a.d = 'b';
dopisz(a, "zad36.txt"); // dopisz linię
vector<A> v = { {1,"2",3.5,'4'},{2,"3",4.5,'5'} };
dopisz(v, "zad36.txt"); // dopisz cały wektor elementów
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 87
Zadanie #2.37
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
//////////////////////////////////////////////////////
// metoda znak po znaku (porównuję pierwszy z ostatnim, drugi z przedostatnim itd.)
bool palindrom(string txt) {
for (int i = 0, k = txt.size() - 1; i <= k; i++, k--) {
if (txt[i] != txt[k]) return false; // jeśli nie są równe, nie może być palindrom
}
return true;
}
// metoda wykorzystująca wbudowane funkcje biblioteki standardowej: assign,
// assign tworzy nowy napis na bazie innego; utworzę nowy
// na podstawie starego, ale traktowanego "od tyłu"
// rbegin() początek, ale od tyłu, rend() koniec od początku :)
// (reverse begin, reverse end)
bool palindrom2(string txt) {
string nowy;
nowy.assign(txt.rbegin(), txt.rend());
return (nowy == txt); // true lub false
}
int main() {
setlocale(LC_ALL, "");
cout << palindrom("krowa") << endl; // nie
cout << palindrom("kajak") << endl; // tak
cout << palindrom("x") << endl; // tak
Zadanie #2.38
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
UL ileAwB(string A, string B) {
UL i = 0;
L poz = -1;
26589ec988c76404b19a97e88c6609a5
2
88 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #2.39
Przykładowe rozwiązanie 1.
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
// wersja zakładająca poprawność napisu
L stol_(string x) {
L xi = 0;
L mnoznik = 1;
bool minus = false;
if (x[0] == '-') {
minus = true;
x = x.substr(1); // nowy napis bez pierwszego znaku '-'
}
while (x.size()) {
// znaki '0', '1' itd. mają wartość liczbową 48, 49 itd. Wykorzystam to.
xi += (x.back() - 48) * mnoznik; // * 1, * 10, * 100...
mnoznik *= 10;
x.pop_back();
}
return (minus) ? -xi : xi;
}
// wersja z poprawnym napisem, ale inny sposób
L stol2_(string x) {
L xi = 0;
vector<L> liczby{ 0,1,2,3,4,5,6,7,8,9 };
string znaki = "0123456789";
L mnoznik = 1;
bool minus = false;
if (x[0] == '-') {
minus = true;
x = x.substr(1);
}
while (x.size()) {
L liczba = liczby[znaki.find(x.back())]; // działa tylko dla poprawnego napisu!
xi += liczba * mnoznik;
mnoznik *= 10;
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 89
x.pop_back();
}
return (minus) ? -xi : xi;
}
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
cout << stol_("3120") << endl;
cout << stol2_("3120") << endl;
cout << stol_("-215") << endl;
cout << stol2_("-215") << endl;
Przykładowe rozwiązanie 2.
#include <iostream>
#include <string>
int main() {
cout << stol_("3120") << endl;
cout << stol_("3120") << endl;
cout << stol_("-215") << endl;
cout << stol_("-215") << endl;
}
26589ec988c76404b19a97e88c6609a5
2
90 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #2.40
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
string L2string(L x) {
string napis = "";
string minus = "";
if (x < 0) { x *= -1; minus = "-"; }
while (x != 0) {
napis = char(x % 10 + 48) + napis;
x /= 10;
}
napis += (napis == "") ? "0" : "";
return minus + napis;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
cout << L2string(1443) << endl;
cout << L2string(-1443) << endl;
cout << L2string(0) << endl;
cout << L2string(-0) << endl;
cout << L2string(+0) << endl;
}
Zadanie #2.41
Przykładowe rozwiązanie 1.
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
UL binary_string2dec(string binary) {
UL dec = 0;
UL potega = binary.size() - 1;
for (auto bit : binary) { // bit to '1' albo '0'
dec += (bit - 48) * pow(2, potega--);
}
return dec;
}
string dec2binary_string(UL dec) {
string binary = "";
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 91
while (dec != 0) {
binary = char((dec % 2) + 48) + binary;
dec /= 2;
}
return binary;
}
// a teraz rozwiązania bardziej uniwersalne niż wcześniejsze, dla dowolnego systemu
// o podstawie 2, 3, ..., 16
UL str2dec(string s, UL podstawa) {
// zwróć uwagę, że pozycja cyfry to jej wartość w systemie dziesiętnym,
// np. 3 ma pozycję 3, a f pozycję 15
string cyfrySystemu = "0123456789abcdef";
UL dec = 0;
UL potega = s.size() - 1;
for (auto cyfra : s) {
UL vpoz = cyfrySystemu.find(cyfra); // pozycja vpoz jest równocześnie wartością
// dziesiętną cyfry
dec += vpoz * pow(podstawa, potega--);
}
return dec;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
cout << binary_string2dec("0") << endl; // 0
cout << binary_string2dec("10001") << endl; // 17
cout << binary_string2dec("11111") << endl; // 31
cout << binary_string2dec("0001001101") << endl; // 77
26589ec988c76404b19a97e88c6609a5
2
92 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Przykładowe rozwiązanie 2.
#include <iostream>
#include <string>
#include <cmath>
int get_decimal_value(char c) {
return isdigit(c) ? c - '0' : c - 'A' + 10;
}
return result;
}
std::string result;
while (value > 0) {
result += get_character_from_value(value % base);
value /= base;
}
result.assign(result.rbegin(), result.rend());
return result;
}
int main() {
std::string value;
int from_base, to_base;
std::cin >> value >> from_base >> to_base;
Zadanie #2.42
#include <iostream>
#include <ctime>
#include <vector>
#include <fstream>
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 93
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
vector<string> szukajLiczb(string T) {
vector<string> wynik;
string cyfry = "0123456789";
bool nowy_fragment = false;
for (char znak : T) {
bool cyfra = (cyfry.find(znak) != string::npos) ? true : false;
if (nowy_fragment and cyfra) wynik.back() += znak; // istnieje podciąg cyfr
else if (cyfra and !nowy_fragment) { // nowy podciąg cyfr
wynik.push_back("");
wynik.back() += znak;
nowy_fragment = true;
}
else { // nie cyfra
nowy_fragment = false;
}
}
return wynik;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
string txt = "abd65asd7891das1d";
for (auto e : szukajLiczb(txt)) {
cout << e << endl;
}
}
Zadanie #2.43
#include <iostream>
#include <ctime>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
// funkcja szuka jednego, najdłuższego (pierwszego) podciągu
string szukajNajdluzszyNiemalejacy(string T) {
string cyfry = "0123456789";
L poczatek = -1, dlugosc = 0;
L maxdl = -1, maxpocz = -1;
for (UL i = 0; i <= T.size() - 1; i++) {
char znak = T[i];
bool cyfra = (cyfry.find(znak) == string::npos) ? false : true;
if (cyfra and dlugosc == 0) { // nowy podciąg jednocyfrowy
poczatek = i;
dlugosc = 1;
}
else if (cyfra and dlugosc > 0) { // trwa podciąg
if (T[i - 1] - 48 <= T[i] - 48) { // zachowana niemalejąca kolejność
26589ec988c76404b19a97e88c6609a5
2
94 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
dlugosc++;
if (maxdl < dlugosc) {
maxdl = dlugosc;
maxpocz = poczatek;
}
}
else {
poczatek = i;
dlugosc = 1;
}
}
else { // nie cyfra
dlugosc = 0;
poczatek = i;
}
}
return T.substr(maxpocz, maxdl);
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
string txt = "dfgnqeiut98tna1223v0w3r1233334asdsh";
cout << szukajNajdluzszyNiemalejacy(txt);
}
Zadanie #2.44
#include <iostream>
#include <ctime>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
const int SIZE = 15;
string trzy_generator() {
string znaki = "abcdef";
string wynik = "";
int ile = 3;
while (ile--)
wynik += znaki[rand() % znaki.size()];
return wynik;
}
bool odpowiedni(string s) {
vector<string> szukane = { "abc","bcd","cde","def" };
for (auto e : szukane)
if (s == e) return true;
return false;
}
bool test(vector<vector<string>>& W, int w, int k) {
if (odpowiedni(W[w][k]) and
odpowiedni(W[w + 1][k]) and
odpowiedni(W[w][k + 1]) and
odpowiedni(W[w + 1][k + 1])) return true;
return false;
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 95
}
void zadanie44(vector<vector<string>>& W) {
for (int w = 0; w < SIZE - 1; w++) {
for (int k = 0; k < SIZE - 1; k++) {
if (test(W, w, k)) {
cout << "Znaleziono dla w= " << w << " k=" << k << endl;
cout << W[w][k] << " ";
cout << W[w][k + 1] << "\n";
cout << W[w + 1][k] << " ";
cout << W[w + 1][k + 1] << "\n";
}
}
}
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
cout << "ZAWARTOŚĆ WYGENEROWANA LOSOWO: \n\n";
vector<vector<string>> W;
W.resize(SIZE, {});
for (auto& e : W) {
for (int i = 1; i <= SIZE; i++) {
e.push_back(trzy_generator());
cout << e.back();
if (i < SIZE) cout << ",";
}
cout << endl;
}
cout << endl;
cout << string(60, '#') << endl;
// dane stałe (dla sprawdzenia, czy wszystko działa)
W.clear(); // usuwam losowy zbiór i ustalam niżej sztywny dla testu
W = {
{"ebb","cbe","beb","bdd","fcf","eed","bdd","cfd","cec","fee","ebf","cba","bff","acf","aee"},
{"ddc","eee","cac","cca","daa","cce","cbd","cad","afa","ced","fcc","cdd","cca","cfc","afd"},
{"dad","afb","bae","ffd","dba","efd","bac","dda","cca","beb","add","fba","bbe","fbd","fab"},
{"dfd","bcd","ecc","bfb","efb","cbb","dcf","afb","aaf","fcd","dee","dba","dca","baa","cee"},
{"fab","fba","efc","dad","caf","bad","dba","afa","fbd","cbf","ccb","fda","cff","eac","bde"},
{"efa","eac","ada","edd","fcd","fae","dff","cab","eab","dcc","dbd","bac","bfe","efe","eec"},
{"ccc","bcc","fbf","afa","abc","cde","fec","faa","bfe","cac","acd","dad","eca","bbe","afd"},
{"eba","abb","cfd","ccb","abc","def","ffc","ead","cdd","baf","bef","fbd","afb","bae","bfe"},
{"fcf","acf","bdc","baa","cdf","adf","edb","cab","ebe","faf","dee","ddc","ebd","aad","eaa"},
{"eee","aec","cbc","edd","bcf","fbb","acc","abf","dbc","cab","bcd","bbc","ebc","fee","fcd"},
{"cdc","cef","bfe","def","ede","ade","ade","dea","cbc","bce","bce","cad","fbb","dbb","ccb"},
{"feb","dba","afe","efa","add","aeb","bfc","bee","aca","acc","ebe","ead","ffa","baa","eca"},
{"eea","fcd","bdf","baf","fdb","fdb","ddd","bce","eed","edf","efc","fca","dff","def","abc"},
{"ebc","fcd","fad","cde","daf","eee","dfd","aaf","cff","dcc","aff","cfb","afc","bcd","cde"},
{"cca","afe","daf","ecf","cfd","cdb","bfe","aea","ffe","dae","bae","fce","ade","bbc","fcd"}
};
zadanie44(W);
}
26589ec988c76404b19a97e88c6609a5
2
96 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #2.45
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
// korzystam z funkcji utworzonej we wcześniejszych zadaniach
bool palindrom(string txt);
int main() {
setlocale(LC_ALL, ""); srand(time(0));
ifstream dane;
dane.open("45_dane.txt");
string wiersz;
vector<string> kolumny;
kolumny.resize(20, "");
// wszystkie wiersze to palindromy
cout << "Wiersze:\n";
while (getline(dane >> std::ws, wiersz)) {
if (palindrom(wiersz)) cout << "(" << wiersz << ")" << endl;
for (int i = 0; i < wiersz.size(); i++) {
kolumny[i] += wiersz[i];
}
}
cout << "\nKolumny:\n";
for (auto kolumna : kolumny) {
if (palindrom(kolumna)) cout << "(" << kolumna << ")" << endl;
}
dane.close();
}
////////////////////////
// funkcje wykorzystane z wcześniejszych zadań
bool palindrom(string txt) {
string nowy;
nowy.assign(txt.rbegin(), txt.rend());
return (nowy == txt); // true lub false
}
Zadanie #2.46
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 97
// można też użyć typu wstring zamiast string, wofstream zamiast ofstream, wchar_t zamiast
// char, wcin zamiast cin, wcout zamiast cout
void zapisz(wstring txt) { // przeciążona
wofstream zapis;
zapis.open("kod2.txt");
for (auto znak : txt) {
zapis << (znak + 0); // kod znaku
zapis << ';';
}
zapis.close();
}
wstring odczytaj2() {
ifstream odczyt;
wstring odczytane = L""s; // wstring ma literały L"treść"s;
string temp;
odczyt.open("kod2.txt");
while (getline(odczyt, temp, ';').good()) {
odczytane += wchar_t(stoi(temp));
}
odczyt.close();
return odczytane;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
string txt;
getline(cin, txt);
zapisz(txt);
wstring txt2;
getline(wcin, txt2);
zapisz(txt2);
26589ec988c76404b19a97e88c6609a5
2
98 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #2.47
#include <iostream>
#include <ctime>
#include <vector>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
UL wystapienia(vector<L>& v, L x) {
UL ile = 0;
for (auto e : v) if (e == x) ile++;
return ile;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
vector<L> v{ 1,2,3,4,5,6,7,6,5,4,3,4,5,6,7 };
cout << wystapienia(v, 7);
}
Zadanie #2.48
#include <iostream>
#include <ctime>
#include <vector>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
bool takie_same(vector<L> v, int pocz, int kon) {
for (int i = pocz; i <= kon - 1; i++)
if (v[i] != v[i + 1]) return false;
return true;
}
void zad48(vector<L> v) {
for (int dlugosc = v.size(); dlugosc >= 2; dlugosc--) { // długości
for (int i = 0; i + dlugosc - 1 < v.size(); i++) {
if (takie_same(v, i, i + dlugosc - 1)) {
for (int s = i; s <= i + dlugosc - 1; s++) cout << v[s] << " ";
cout << "od pozycji " << i << " do pozycji " << i + dlugosc - 1 << endl;
}
}
}
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
zad48({ 3,2,1,1,4,2,4,4,4 });
zad48({ 1,1,2,3,2,2,3,3,1,1,5,3,2,6,7,4,3,3,3,3,3,1,6,9 });
}
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 99
Zadanie #2.49
#include <iostream>
#include <vector>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
bool jest(vector<int> v, int x) {
for (auto e : v) if (x == e) return true;
return false;
}
vector<int> czesc_wspolna_bez_powtorzen(vector<int> A, vector<int> B) {
vector<int> cw;
for (auto e : A) {
for (auto f : B) {
if (e == f and !jest(cw, e)) {
cw.push_back(e);
break;
}
}
}
return cw;
}
int main() {
setlocale(LC_ALL, "");
for (auto e : czesc_wspolna_bez_powtorzen({ 6,1,2,3,4,5,6,6,6,7,7,7 },
´{ 4,5,6,7,7 }))
cout << e << " ";
}
Zadanie #2.50
#include <iostream>
#include <ctime>
#include <vector>
#include <string>
using namespace std;
//////////////////////////////////////////////////////
string zad50(string txt, int usun = 2) {
bool del;
cout << "przed: " << txt << endl;
do {
del = false;
for (int i = 1; i < txt.size(); i++) {
if (txt[i] == txt[i - 1]) {
txt.erase(i - 1, usun);
del = true;
break;
}
}
} while (del);
return txt;
}
int main() {
26589ec988c76404b19a97e88c6609a5
2
100 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #2.51
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
bool czyPierwsza(UL i) {
if (i <= 1) return false;
for (UL dzielnik = 2; dzielnik <= sqrt(i); dzielnik++)
if (i % dzielnik == 0) return false;
return true;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
cout << czyPierwsza(10) << " ";
cout << czyPierwsza(13) << " ";
}
Zadanie #2.52
#include <iostream>
#include <vector>
using namespace std;
//////////////////////////////////////////////////////
vector<double> przeplatanka(vector<double> a, vector<double> b) {
vector<double> c;
auto apoz = a.begin();
auto bpoz = b.begin();
do {
if (apoz != a.end()) {
c.push_back(*apoz);
apoz++;
}
if (bpoz != b.end()) {
c.push_back(*bpoz);
bpoz++;
}
} while (apoz != a.end() or bpoz != b.end());
return c;
}
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 101
int main() {
setlocale(LC_ALL, "");
for (auto e : przeplatanka({ 1,2,3,4,5,6,7,8,9,10 }, { 20,30,40,50,60 }))
cout << e << " ";
}
Zadanie #2.53
#include <iostream>
#include <ctime>
#include <vector>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
bool poprawny(string wyr) {
cout << "\nBadam= " << wyr << endl;
string litery = "qazwsxedcrfvtgbyhnujmikolp";
string operacje = "+-*/^%"; // do tego nawiasy () oraz =
string cyfry = "0123456789";
// algorytm oprę na redukcji części poprawnych
// do innych poprawnych, ale krótszych, np.:
// 1+1 zredukuję do 1, a+b do a, (1) do 1 itd.
/* Uwaga! Algorytm wydaje mi się skuteczny. Nie znalazłem jak
do tej pory kontrprzykładu, który wykazuje jego złe działanie. */
////////////////////////////////////////////////////////
// zamieniam każdą cyfrę na 1
for (auto& e : wyr) if (cyfry.find(e) != string::npos) e = '1';
// redukuję wszystkie ciągi cyfr, np. 1111 na 1
size_t poz;
while ((poz = wyr.find("11")) != string::npos)
wyr.replace(poz, 2, "1");
// zamieniam litery na "a"
for (auto& e : wyr) if (litery.find(e) != string::npos) e = 'a';
// zamieniam "1" na "a"
for (auto& e : wyr) if (e == '1') e = 'a';
// zmieniam działania na jedno działanie '-' (nie ruszam =)
for (auto& e : wyr)
if (e != '-' and operacje.find(e) != string::npos) e = '-';
// redukuję do oporu "(a)" oraz "(-a)" do "a" oraz redukuję "a-a" do "a"
string temp;
do {
temp = wyr;
while ((poz = wyr.find("(a)")) != string::npos)
wyr.replace(poz, 3, "a");
while ((poz = wyr.find("(-a)")) != string::npos)
wyr.replace(poz, 4, "a");
while ((poz = wyr.find("a-a")) != string::npos)
wyr.replace(poz, 3, "a");
} while (wyr != temp);
// redukuję a=a do a
while ((poz = wyr.find("a=a")) != string::npos)
wyr.replace(poz, 3, "a");
// wyr musi być "a" lub "-a", jeżeli jest poprawne
cout << "Po redukcji " << wyr << endl;
return (wyr == "a" or wyr == "-a" or wyr == "");
26589ec988c76404b19a97e88c6609a5
2
102 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
int main() {
setlocale(LC_ALL, ""); srand(time(0));
// 1 (true): poprawny, 0 (false): niepoprawny
cout << poprawny("-3*x+781/a=2+(1*a)-3/b%10+(1)-(-a)/100") << endl;
cout << poprawny("a+b-c(") << endl;
cout << poprawny("a+b-c=d*(-1123)") << endl;
cout << poprawny("") << endl; // pusty napis zawierający wyrażenie uznajmy za poprawny
cout << poprawny("-a-a-xx") << endl;
cout << poprawny("--10") << endl; // uznajemy za niepoprawny, nie namnażamy minusów
cout << poprawny("-(-10)") << endl; // ale taki jest już poprawny przez wzgląd na nawias
cout << poprawny("1+(=a=a)") << endl;
cout << poprawny("10^((a+b+43587*4)+(-10/a*b)+(u+i+g%10)/(-7-1/10))") << endl;
cout << poprawny("a/(a=b)") << endl;
cout << poprawny("))a+b((") << endl;
cout << poprawny("a==b") << endl;
}
Zadanie #2.54
Wersja prosta
imiona.txt
Bogdan
Magda
Barbara
Tobiasz
Odorian
Kapustan
Śliwianna
Waldemaria
Wanna
Brytfanka
Pomiar
Bodziomił
Gryczan
Karaczanna
Melisa
Amebon
Mikser
nazwiska.txt
Kowalski
Nowak
Abecadłowski
Brutusowicz
Cebulak
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 103
Dobrodziej
Emulatorski
Fajczyński
Gromosławski
Hamburgerowicz
Iwański
Jabłoński
Kod:
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
string generate() {
ifstream imiona, nazwiska;
imiona.open("imiona.txt");
nazwiska.open("nazwiska.txt");
vector<string> vimiona, vnazwiska;
string temp;
while (getline(imiona, temp).good())
vimiona.push_back(temp);
while (getline(nazwiska, temp).good())
vnazwiska.push_back(temp);
imiona.close();
nazwiska.close();
return string(vimiona[rand() % vimiona.size()]
+ " " + vnazwiska[rand() % vnazwiska.size()]);
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
cout << generate() << endl;
cout << generate() << endl;
cout << generate() << endl;
cout << generate() << endl;
}
26589ec988c76404b19a97e88c6609a5
2
104 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Śliwianna;k
Waldemaria;k
Wanna;k
Brytfanka;k
Pomiar;m
Bodziomił;m
Gryczan;m
Karaczanna;k
Melisa;k
Amebon;mk
Mikser;m
nazwiska.txt
Kowalski;Kowalska
Nowak;Nowak
Abecadłowski;Abecadłowska
Brutusowicz;Brutusowicz
Cebulak;Cebulak
Dobrodziej;Dobrodziej
Emulatorski;Emulatorska
Fajczyński;Fajczyńska
Gromosławski;Gromosławska
Hamburgerowicz;Hamburgerowicz
Iwański;Iwańska
Jabłoński;Jabłońska
Kod:
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
string generate() {
ifstream imiona, nazwiska;
imiona.open("imiona.txt");
nazwiska.open("nazwiska.txt");
vector<string> vimiona, vnazwiska;
string temp;
while (getline(imiona, temp).good())
vimiona.push_back(temp);
while (getline(nazwiska, temp).good()) {
vnazwiska.push_back(temp);
}
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 105
imiona.close();
nazwiska.close();
poz = ntemp.find(";");
nazwisko = (plec == "k") ? ntemp.substr(poz + 1) : ntemp.substr(0, poz);
Zadanie #2.55
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
string sylaba_generator(string srodek = "eo",
string prefix = "srjcg",
string postfix = "wrtpsdfghjklzcbnm") {
string sylaba = "";
return ((sylaba += prefix[rand() % prefix.size()])
+= srodek[rand() % srodek.size()])
+= postfix[rand() % postfix.size()];
}
string generuj() {
string imie("");
int sylab = rand() % 4 + 1; // 1-4
if (sylab & 1) { // nieparzysta liczba sylab
vector<string> srodki{ "e","o" };
int poz_srodek = rand() % 2;
for (int i = 1; i <= sylab; i++) {
imie += sylaba_generator(srodki[poz_srodek]);
poz_srodek = (poz_srodek + 1) % 2;
}
}
else { // parzysta liczba sylab
26589ec988c76404b19a97e88c6609a5
2
106 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #2.56
#include <iostream>
#include <ctime>
#include <vector>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
string cyfra_na_string(int c) {
char znak = c + 48; // 0 -> '0'
string wynik;
wynik += znak; // '0' -> "0"
return wynik;
}
string zad56() {
vector<int> cyfry = { 0,1,2,3,4,5,6,7,8,9 };
vector<int> wylosowane;
UL suma = 0;
do {
if (wylosowane.size() < 9) {
// losuję, ale bez pierwszej pozycji czyli od {1, 2, 3, ..., 9}, pomijam 0
int wylosowana_pozycja = rand() % (cyfry.size() - 1) + 1;
// uwaga na parzystą na trzeciej pozycji
if (wylosowane.size() == 2 and cyfry[wylosowana_pozycja] % 2 == 0) continue;
wylosowane.push_back(cyfry[wylosowana_pozycja]);
suma += wylosowane.back();
// teraz zapewniam sobie, że w następnym losowaniu nie zostanie wylosowana ta sama cyfra
cyfry[wylosowana_pozycja] = cyfry[0];
cyfry[0] = wylosowane.back();
}
else { // ostatnia cyfra nie ma znaczenia, może się powtarzać
wylosowane.push_back(cyfry[rand() % cyfry.size()]);
suma += wylosowane.back();
}
if (wylosowane.size() == 10 and suma < 30) {
cout << "Losuję ponownie, za mała suma! (" << suma << ")\n[";
for (auto e : wylosowane) cout << e << " ";
cout << "]\n";
wylosowane.clear(); // od nowa, zła suma
suma = 0;
cyfry = { 0,1,2,3,4,5,6,7,8,9 }; // reset
}
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 107
Zadanie #2.57
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
struct Punkt {
int x;
int y;
};
bool na_linii(Punkt a, Punkt b, Punkt c) {
// (y−yA)(xB−xA)−(yB−yA)(x−xA)=0 // wzór funkcji dla dwóch punktów. Punkt c spełnia poniższą
// równość, gdy leży na prostej utworzonej z punktów a i b.
return ((c.y - a.y) * (b.x - a.x) - (b.y - a.y) * (c.x - a.x) == 0);
}
bool zad57(Punkt a, Punkt b, Punkt c) {
// Testujemy, czy punkty a i b to linia, a punkt c leży na tej linii. Kombinacje a, c, b oraz b, c, a nie
// są konieczne, zwracają jednak uwagę na fakt, że prostą mogą tworzyć inne dwa punkty.
return (na_linii(a, b, c) or na_linii(a, c, b) or na_linii(b, c, a));
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
cout << zad57 ({ 0,0 }, { 10,10 }, { 5,5 }); // wszystkie leżą na prostej x=y (1)
cout << zad57 ({ 0,0 }, { 10,10 }, { 1,-1 }); // nie leżą (0)
cout << zad57 ({ 0,0 }, { 10,10 }, { -1,-1 }); // leżą (1)
cout << zad57 ({ 0,0 }, { 0,5 }, { 2,0 }); // nie leżą (0)
cout << zad57 ({ 0,0 }, { 0,5 }, { 0,2 }); // leżą (1) (uwaga: te punkty tworzą pionową
// linię, a podany wzór redukuje się do x=0)
}
Zadanie #2.58
#include <iostream>
#include <ctime>
#include <vector>
#include <string>
using namespace std;
//////////////////////////////////////////////////////
struct Punkt {
double x;
double y;
26589ec988c76404b19a97e88c6609a5
2
108 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
};
string liniowa(Punkt a, Punkt b) {
// (y−yA)(xB−xA)−((yB−yA)(x−xA))=0 // wzór funkcji dla dwóch punktów
if (b.x - a.x == 0) return "problem z dzieleniem przez zero\n";
/* po przekształceniu mamy coś takiego:
f(x) = x(yb-ya)/(xb-xa) + ya-xa(yb-ya)/(xb-xa);
*/
string wynik;
wynik = "f(x) = ";
wynik += to_string((b.y - a.y) / (b.x - a.x));
wynik += " * x ";
double bwsp = -a.x * (b.y - a.y) / (b.x - a.x) + a.y;
if (bwsp >= 0) wynik += "+";
wynik += to_string(bwsp);
return wynik;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
cout << liniowa({ 0,0 }, { 5,5 }) << endl; // f(x) = x
cout << liniowa({ -2,0 }, { 2,-1 }) << endl; // f(x) = -1/4 * x - 1/2
cout << liniowa({ 0,0 }, { 2,4 }) << endl; // f(x) = 2 * x;
cout << liniowa({ 0,0 }, { 0,4 }) << endl; // pionowa linia to w zasadzie nie jest funkcja
}
Zadanie #2.59
#include <iostream>
#include <ctime>
#include <vector>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
vector<int> dni{ 31,28,31,30,31,30,31,31,30,31,30,31 };
vector<int> dnip{ 31,29,31,30,31,30,31,31,30,31,30,31 };
vector<string> mies{ "styczeń","luty","marzec","kwiecień","maj","czerwiec",
"lipiec","sierpień","wrzesień","październik","listopad","grudzień" };
vector<string> dzien{ "poniedziałek","wtorek","środa","czwartek","piątek",
´"sobota","niedziela" };
int STARTOWY = 5; // indeks soboty w vector<string> dzien;
// zasada - kiedy rok jest przestępny?
// gdy rok jest podzielny przez 4, ale nie przez 100, lub gdy jest podzielny przez 400
bool przestepny(UL rok) {
return ((rok % 4 == 0 and rok % 100 != 0) or (rok % 400 == 0));
}
// ile dni w roku?
int ile_dni_ma_rok(UL rok) {
if (przestepny(rok)) return 366;
return 365;
}
// tylko rok 2022
string dzien_roku_2022(int N) {
if (N < 1 or N>365) return "funkcja działa w zakresie N<1;365>";
string d = "";
int m = 0; // początkowy miesiąc to styczeń mies[m]
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 109
string d = "";
// dla roku 2022 wykorzystam funkcję dzien_roku_2022
if (rok == 2022) return dzien_roku_2022(N);
// dla dalszych lat > 2022 obliczę, ile dni minęło od 2022-01-01 do końca
// roku poprzedzającego rok przekazany do funkcji
UL ile_dni = 0;
for (UL r = rok - 1; r >= 2022; r--) {
ile_dni += ile_dni_ma_rok(r);
}
// dzień zwracany przez funkcję
int nrd = (STARTOWY + ile_dni + N - 1) % 7;
26589ec988c76404b19a97e88c6609a5
2
110 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #2.60
#include <iostream>
#include <ctime>
#include <vector>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
string format2(L v) {
if (v <= 9) return "0" + to_string(v);
return to_string(v);
}
string roznica_czasu(string t1, string t2) {
L t2_sek = stoi(t2.substr(0, 2)) * 3600 + stoi(t2.substr(3, 2)) * 60 +
´stoi(t2.substr(6, 2));
L t1_sek = stoi(t1.substr(0, 2)) * 3600 + stoi(t1.substr(3, 2)) * 60 +
´stoi(t1.substr(6, 2));
L t = abs(t2_sek - t1_sek);
L tg = t / 3600;
L tm = (t - tg * 3600) / 60;
L ts = t - tg * 3600 - tm * 60;
return format2(tg) + ":" + format2(tm) + ":" + format2(ts);
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
cout << roznica_czasu("09:05:08", "13:10:33") << endl;
cout << roznica_czasu("13:10:33", "09:05:08") << endl;
cout << roznica_czasu("09:35:08", "13:10:33") << endl;
cout << roznica_czasu("24:00:00", "00:00:01") << endl;
cout << roznica_czasu("24:00:00", "00:00:00") << endl; // a może 0? :)
}
Zadanie #2.61
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <fstream>
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 111
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
pair<wstring, wstring> alfabetycznie(wstring t1, wstring t2) {
wstring alfabet = L"aąbcćdeęfghijklłmnńoóprsśtuwxyźż";
// napisy nie mogą być puste
if (t1 == L"" or t2 == L"") {
cout << "napisy nie mogą być puste!\n";
return make_pair(t1, t2);
}
// test czy napis ma właściwe litery (dozwolone)
if (t1.find_first_not_of(alfabet) != wstring::npos) {
wcout << t1 << L": ";
cout << "napis zawiera niedozwolone znaki\n";
return make_pair(t1, t2);
}
if (t2.find_first_not_of(alfabet) != wstring::npos) {
wcout << t2 << L": ";
cout << "napis zawiera niedozwolone znaki\n";
return make_pair(t1, t2);
}
// testy na kolejność alfabetyczną (size_t to typ zwracany przez .size()) (to taki dodatni int)
for (size_t a = 0, b = 0; a < t1.size() and b < t2.size(); ) {
if (alfabet.find(t1[a]) < alfabet.find(t2[b])) {
return make_pair(t1, t2);
}
else if (alfabet.find(t1[a]) > alfabet.find(t2[b])) {
return make_pair(t2, t1);
}
else {
a++;
b++;
}
}
// wszystkie litery się zgadzają, tylko długość pozostaje do sprawdzenia
if (t1.size() <= t2.size()) return make_pair(t1, t2); // t1 krótsze, więc wcześniej
return make_pair(t2, t1); // t2 krótsze
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
// wyłapane błędy
alfabetycznie(L"", L"transformator");
alfabetycznie(L"ko tek", L"pie sek");
cout << endl;
26589ec988c76404b19a97e88c6609a5
2
112 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #2.62
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
UL odwracanie_cyfr(UL n) {
vector<UL> cyfry;
while (n != 0) {
cyfry.push_back(n % 10);
n /= 10;
}
UL r = 0, poz = 1;
for (int i = 0; i < cyfry.size(); i++) {
r += cyfry[i] * pow(10, cyfry.size() - 1 - i);
}
return r;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
Zadanie #2.63
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
int main() {
setlocale(LC_ALL, ""); srand(time(0));
// dane z pliku włożymy sobie do vector<vector<L>>
vector<vector<L>> dane;
int kolumna = 0;
ifstream d;
// odczyt
d.open("63_dane.txt");
while (!d.eof()) {
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 113
L temp;
d >> temp;
if (!d.fail()) {
if (kolumna == 0) dane.push_back({});
dane.back().push_back(temp);
}
kolumna = (kolumna + 1) % 6;
}
d.close();
// prezentacja danych z pliku
for (auto e : dane) {
for (auto f : e) {
cout << f << " ";
}
cout << "\n";
}
// jaka jest średnia liczb w pierwszej i ostatniej kolumnie?
double srp = 0, sro = 0;
int np = 0, no = 0;
for (int i = 0; i < dane.size(); i++) {
for (int j = 0; j < dane[i].size(); j++) {
if (j == 0) {
srp += dane[i][j];
np++;
}
else if (j == dane[i].size() - 1) {
sro += dane[i][j];
no++;
}
}
}
cout << "średnia w pierwszej kolumnie = " << srp / np << endl;
cout << "średnia w ostatniej kolumnie = " << sro / no << endl;
// które kolumny (numer) posiadają największą liczbę?
L maks = dane[0][0];
for (int i = 0; i < dane.size(); i++) {
for (int j = 0; j < dane[i].size(); j++) {
if (maks < dane[i][j]) maks = dane[i][j]; // znajdź maksa
}
}
vector<int> kolumny;
for (int i = 0; i < dane.size(); i++) {
for (int j = 0; j < dane[i].size(); j++) {
if (maks == dane[i][j]) kolumny.push_back(j + 1);
}
}
cout << "Największa liczba = " << maks << " znajduje się w kolumnach: ";
for (auto e : kolumny) cout << e << " ";
cout << endl;
// ile jest wierszy, w których nie występuje liczba podzielna przez 10?
int ile_wierszy = 0;
for (int i = 0; i < dane.size(); i++) {
bool nie_wystepuje = true;
for (int j = 0; j < dane[i].size(); j++) {
if (dane[i][j] % 10 == 0) {
nie_wystepuje = false;
26589ec988c76404b19a97e88c6609a5
2
114 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
break;
}
}
if (nie_wystepuje) {
ile_wierszy++;
cout << "wiersz nr:" << i + 1 << ":brak podz. przez 10 (";
for (auto e : dane[i]) cout << e << " ";
cout << ")\n";
}
}
cout << "W " << ile_wierszy << " wierszach nie występuje liczba podzielna przez 10.\n";
// ile jest wierszy, w których pierwsze trzy liczby zachowują niemalejący porządek?
ile_wierszy = 0;
for (int i = 0; i < dane.size(); i++) {
if (dane[i][0] <= dane[i][1] and dane[i][1] <= dane[i][2]) {
cout << "niemalejący porządek: " << dane[i][0] << " " <<
dane[i][1] << " " << dane[i][2] << endl;
ile_wierszy++;
}
}
cout << "W " << ile_wierszy << " wierszach 3 pierwsze liczby mają niemalejący
´porządek.\n";
// ile jest wierszy, w których są dokładnie 3 liczby z zakresu <85;100>?
ile_wierszy = 0;
for (int i = 0; i < dane.size(); i++) {
int trzy = 0;
for (int j = 0; j < dane[i].size(); j++) {
if (dane[i][j] >= 85 and dane[i][j] <= 100) trzy++;
}
if (trzy == 3) {
ile_wierszy++;
cout << "W wierszu " << i + 1 << " dokładnie 3 liczby są <85;100>\n";
}
}
cout << "W " << ile_wierszy << " wierszach dokładnie 3 liczby są między
´<85;100>\n";
}
Zadanie #2.64
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
int main() {
setlocale(LC_ALL, ""); srand(time(0));
string osoby = "ABCDE"; // pozycja osoby to jej numer, np. "A" to 0, "B" to 1 itd.
vector<vector<pair<int, int>>> dane; // pair<dzien, pomiar>
dane.resize(osoby.size()); // każda osoba ma swój wektor z danymi,
// "A" ma dane[0], "B" dane[1] itd.
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 115
ifstream p;
p.open("64_dane.txt");
while (!p.eof()) {
string osoba;
int pomiar;
int dzien;
p >> osoba;
p >> pomiar;
p >> dzien;
if (p.fail()) break;
auto o = osoby.find(osoba);
dane[o].push_back(make_pair(dzien, pomiar));
}
p.close();
// prezentacja posegregowanych pomiarów
for (int i = 0; i < dane.size(); i++) {
cout << "Osoba " << osoby[i] << ":\n";
for (auto wpis : dane[i]) {
cout << "\t dzien=" << wpis.first << " pomiar=" << wpis.second << "\n";
}
}
// odpowiedzi:
// która osoba dokonywała najwięcej pomiarów?
int maks_pomiarow = 0;
int nr_osoby = 0;
for (int i = 0; i < dane.size(); i++) {
cout << osoby[i] << " = " << dane[i].size() << endl;
if (maks_pomiarow < dane[i].size()) {
maks_pomiarow = dane[i].size();
nr_osoby = i;
}
}
cout << "Osoba " << osoby[nr_osoby]
<< " dokonała najwięcej pomiarów. " << maks_pomiarow << "\n";
// policz sumę oraz średnią wszystkich pomiarów dla każdej z osób
for (int i = 0; i < dane.size(); i++) {
cout << "Osoba " << osoby[i] << " ";
L suma = 0;
for (auto e : dane[i]) suma += e.second;
cout << "suma = " << suma << " średnia = " << suma * 1.0 / dane[i].size() <<
´endl;
}
// zakładając, że pierwszy dzień pomiarów to wtorek, drugi środa itd.,
// policz sumę pomiarów ze wszystkich wtorków
L suma = 0;
for (int d = 1; d <= 100; d += 7) { // wtorki
for (int i = 0; i < dane.size(); i++) {
for (pair<int, int> wpis : dane[i]) {
if (wpis.first == d) {
suma += wpis.second;
break;
}
}
}
}
cout << "Suma pomiarów z wtorków to = " << suma << endl;
}
26589ec988c76404b19a97e88c6609a5
2
116 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #2.65
#include <iostream>
#include <ctime>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
/*
W zadaniu wykorzystamy proponowane wcześniej rozwiązania, takie jak str2dec().
*/
// liczba (string) z dowolnego systemu na dziesiętny
UL str2dec(string s, UL podstawa) {
// zwróć uwagę, że pozycja cyfry to jej wartość w systemie dziesiętnym,
// np. 3 ma pozycję 3, a f pozycję 15
string cyfrySystemu = "0123456789abcdef";
UL dec = 0;
UL potega = s.size() - 1;
for (auto cyfra : s) {
UL vpoz = cyfrySystemu.find(cyfra);
dec += vpoz * pow(podstawa, potega--);
}
return dec;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
string dane =
"xfac8*1101011*1110100xc8x32xff*1010o7311o1212xabcd*101*1*0x1o0xd*11111";
UL podstawa = 0; // 2, 8, 16
string temp = "";
for (int poz = 0; poz < dane.size(); poz++) {
if (dane[poz] == 'x' or dane[poz] == 'o' or dane[poz] == '*') {
if (temp != "") {
cout << temp << " (" << podstawa << ")= " << str2dec(temp, podstawa) <<
´endl;
}
temp = "";
}
else {
temp += dane[poz];
}
if (dane[poz] == 'x') {
podstawa = 16;
}
else if (dane[poz] == 'o') {
podstawa = 8;
}
else if (dane[poz] == '*') {
podstawa = 2;
}
}
if (temp != "") {
cout << temp << " = " << str2dec(temp, podstawa) << endl;
}
}
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 117
Zadanie #2.66
#include <iostream>
#include <ctime>
#include <vector>
#include <cmath>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
vector<vector<L>> mnozenie_macierzy(L a, vector<vector<L>> m) {
vector<vector<L>> wynik;
wynik.resize(m.size());
for (int wiersz = 0; wiersz < m.size(); wiersz++) {
for (L x : m[wiersz]) {
wynik[wiersz].push_back(a * x);
}
}
return wynik;
}
vector<vector<L>> mnozenie_macierzy(vector<vector<L>>m1, vector<vector<L>> m2) {
if (m1[0].size() != m2.size()) {
cout << "Mnożenie nie może się udać.\n" <<
"Liczba kolumn w macierzy A musi być\n" <<
"równa liczbie wierszy w macierzy B.\n";
return { {} };
}
vector<vector<L>> wynik;
wynik.resize(m1.size());
for (int wiersz = 0; wiersz < m1.size(); wiersz++) {
int kolumn_m2 = m2[0].size();
for (int k = 0; k < kolumn_m2; k++) {
L suma = 0;
int poz = 0;
for (poz = 0; poz < m1[wiersz].size(); poz++) {
suma += m1[wiersz][poz] * m2[poz][k];
}
wynik[wiersz].push_back(suma);
}
}
return wynik;
}
void pokaz_macierz(vector<vector<L>>& m) {
for (auto w : m) {
for (auto e : w) {
cout << e << " ";
}
cout << endl;
}
cout << "\n----------------------------\n";
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
26589ec988c76404b19a97e88c6609a5
2
118 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
// rozwiązanie
vector<vector<L>> m1 = { {2,4,9,4},{3,0,2,2},{7,3,1,8},{1,2,3,4},{9,6,3,1} };
vector<vector<L>> w = mnozenie_macierzy(7, m1);
pokaz_macierz(w);
// rozwiązanie
vector<vector<L>> m2 = { {5,9,-1},{7,4,0},{-3, 5, 2} };
vector<vector<L>> m3 = { {4,8,2},{11,-2, 0},{3, 5, 3} };
w = mnozenie_macierzy(m2, m3);
pokaz_macierz(w);
Zadanie #2.67
#include <iostream>
#include <ctime>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
bool palindrom(string txt) {
for (int s = 0, k = txt.size() - 1; s <= k; s++, k--) {
if (txt[s] != txt[k]) return false;
}
return true;
}
vector<string> palindromy(string baza) {
vector<string> r;
string alfabet = "qazwsxedcrfvtgbyhnujmikolp";
for (int dl = 2; dl <= baza.size() - 1; dl++) {
for (int poz = 0; poz + dl <= baza.size() - 1; poz++) {
string temp = baza.substr(poz, dl);
if (palindrom(temp)) r.push_back(temp);
}
}
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 119
return r;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
for (auto e : palindromy("kajakrobbokonstruktorbabajaganogimajakpajakapiraci
´krzyczaaghrrrrhga"))
cout << e << endl;
}
Zadanie #2.68
#include <iostream>
#include <ctime>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
bool podzielna(L N, L p) {
while (N >= p) N -= p;
if (N == 0) return true;
return false;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
cout << podzielna(100, 10) << endl; // tak
cout << podzielna(100, 12) << endl; // nie
cout << podzielna(153, 51) << endl; // tak
cout << podzielna(1, 10) << endl; // nie
cout << podzielna(10, 1) << endl; // tak
cout << podzielna(7, 7) << endl; // tak
}
Zadanie #2.69
#include <iostream>
#include <ctime>
#include <vector>
#include <fstream>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
vector<int> oddo(int zakres_od, int zakres_do) {
vector<int> w;
int krok = 1;
if (zakres_od > zakres_do) krok = -1;
for (int i = zakres_od; i != zakres_do; i += krok)
w.push_back(i);
w.push_back(zakres_do);
return w;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
// prezentacja funkcji oddo
for (auto e : oddo(-5, 5)) cout << e << " ";
26589ec988c76404b19a97e88c6609a5
2
120 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
Zadanie #2.70
#include <iostream>
#include <ctime>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
string sgen(int minL, int maxL, string dict) {
string r ="";
int dl = rand() % (maxL - minL + 1) + minL; // długość napisu
for (int i = 1; i <= dl; i++)
r += dict[rand() % dict.size()];
return r;
}
// pokazuje powtarzające się słowa (pierwszy pomysł)
bool pokaz(vector<string> v) {
vector<string> powt;
for (int i = 0; i <= v.size() - 2; i++) {
bool znaleziony = false;
for (int test = i + 1; test <= v.size() - 1; test++) {
if (v[i] == v[test]) {
if (!znaleziony) powt.push_back(v[i]);
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 121
znaleziony = true;
}
}
}
if (powt.size()) {
for (auto e : powt) cout << e << " ";
return true;
}
return false;
}
// inna wersja (pomysł z pewną optymalizacją)
// polega na porównywaniu tylko tych napisów, które mają tę samą długość,
// najpierw jednak trzeba wektor rozbić na fragmenty napisów o odpowiednich
// długościach (nie będę porównywać pięcioznakowych napisów z siedmioznakowymi).
// Ten pomysł skraca czas wykonania. Mimo tego, że korzysta się w nim z wcześniejszej funkcji
// pokaz(), to jednak ogranicza się ilość porównań.
void pokaz2(vector<string>& v) {
vector<vector<string>> segregacja;
segregacja.resize(6); // [0]=5dl, [1]=6dl ... [5]=10dl
for (auto e : v) {
segregacja[e.size() - 5].push_back(e);
}
for (int s = 0; s <= segregacja.size() - 1; s++) { // kolejne wektory
pokaz(segregacja[s]);
}
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
// generowanie
vector<string> v;
v.resize(25000);
for (auto& e : v) e = sgen(5, 10, "qazwsxedcrfvtgby");
// rozwiązanie 1.
auto pocz = time(0);
pokaz(v);
auto kon = time(0);
cout << "\nprzybliżony czas w sekundach:" << kon - pocz << endl;
// rozwiązanie 2.
pocz = time(0);
pokaz2(v);
kon = time(0);
cout << "\nprzybliżony czas w sekundach:" << kon - pocz << endl;
}
Zadanie #2.71
#include <iostream>
#include <ctime>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
26589ec988c76404b19a97e88c6609a5
2
122 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
//////////////////////////////////////////////////////
struct Opad {
UL sekunda;
UL sztuk;
};
struct Drzewo {
UL sztuk = 3000;
UL czas_opadania = 0;
vector<Opad> opadanie;
};
// cechy opadania
Opad opad() {
UL sek = rand() % 10 + 1;
int szansa = rand() % 100 + 1;
UL sztuk;
if (szansa <= 50) {
sztuk = rand() % 4; // 0-3
}
else if (szansa <= 80) {
sztuk = rand() % 4 + 4; // 4-7
}
else {
sztuk = rand() % 3 + 8; // 8-10
}
return Opad{ sek,sztuk };
}
// tworzenie historii opadania
void zdarzenie(Drzewo& d) {
d.opadanie.push_back(opad());
if (d.sztuk < d.opadanie.back().sztuk) {
d.opadanie.back().sztuk = d.sztuk;
}
d.sztuk -= d.opadanie.back().sztuk; // tyle liści z drzewa spadło
d.czas_opadania += d.opadanie.back().sekunda; // tyle trwa łącznie proces opadania
}
void symulacja_opadania(Drzewo& d) {
while (d.sztuk > 0) {
zdarzenie(d);
cout << "Po " << d.czas_opadania << " sekundach pozostało " << d.sztuk <<
´" liści.\n";
}
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
Drzewo D;
symulacja_opadania(D);
// spis wydarzeń (przywróć poniższy komentarz, jeżeli chcesz zobaczyć kolejne wydarzenia)
// for (Opad o: D.opadanie) cout << o.sekunda << "sek " << o.sztuk << "szt\n";
// odpowiedzi do symulacji
// po jakim czasie (podaj w godzinach, minutach i sekundach) drzewo straciło wszystkie liście? [1,]
cout << "OPADANIE: " << D.czas_opadania << "sek, czyli:\n";
UL g;
UL m;
UL s;
g = D.czas_opadania / 3600;
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 123
// ile razy w krokach symulacji nie spadł ani jeden liść? (losowało się 0 liści) [1,]
// powinna to być 1/4 z około 50%, czyli w okolicach 12,5% (uruchom symulację kilka razy)
UL ile0 = 0;
for (Opad& o : D.opadanie) if (o.sztuk == 0) ile0++;
cout << "Procent opadania liści w ilościach równych 0 wynosi "
<< ile0 * 1.0 / maks * 100.0 << "%" << endl;
Zadanie #2.72
#include <iostream>
#include <ctime>
#include <string>
#include <bitset>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
bool bitowy_palindrom(UL b, UL p = 8) {
bitset<8> lewo8 = 0b10000000;
bitset<8> prawo8 = 0b00000001;
bitset<16> lewo16 = 0b1000000000000000;
bitset<16> prawo16 = 0b0000000000000001;
bitset<8> b8 = b;
26589ec988c76404b19a97e88c6609a5
2
124 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
bitset<16> b16 = b;
for (int przesuniecie = 1; przesuniecie <= p / 2 - 1; przesuniecie++) {
if (p == 8) {
if ((b8 & lewo8) == 0 xor (b8 & prawo8) == 0) return false;
lewo8 = lewo8 >> 1;
prawo8 = prawo8 << 1;
}
else {
if ((b16 & lewo16) == 0 xor (b16 & prawo16) == 0) return false;
lewo16 = lewo16 >> 1;
prawo16 = prawo16 << 1;
}
}
return true;
}
int main() {
setlocale(LC_ALL, ""); srand(time(0));
cout << bitowy_palindrom(0b11100111) << endl; // tak
cout << bitowy_palindrom(0b01100110) << endl; // tak
cout << bitowy_palindrom(0b10011001) << endl; // tak
cout << bitowy_palindrom(0b10011111) << endl; // nie
cout << bitowy_palindrom(0b10111001) << endl; // nie
cout << bitowy_palindrom(0b01111111) << endl; // nie
Zadanie #2.73
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
void bez0(string& b) { // usuwam zbędne 0 z początku
while (b[0] == '0') b.erase(0, 1);
}
// obsługuje przekazywanie "dalej" podczas dodawania
// 0+0 to 0, 1+0 oraz 0+1 to 1, 1+1 to 0 i 1 dalej,
// 1+1+1 to 1 i 1 dalej
string dalej(int& i,int dodaj) {
i += dodaj;
if (i == 0) {
return "0";
}
else if (i == 1) {
i = 0;
return "1";
26589ec988c76404b19a97e88c6609a5
2
ROZWIĄZANIA 125
}
else if (i == 2) {
i = 1;
return "0";
}
else if (i == 3) {
i = 1;
return "1";
}
else {
cout << "Jakiś dramat, źle dodajemy?\n";
return "X";
}
}
string dodaj(string b1, string b2) {
// czyszczę początkowe zera
bez0(b1); bez0(b2);
cout << b1 << endl << "+ " << b2 << endl;
string suma="";
int d = 0;
int s = 0;
L wlewo = 0;
L poz1 = b1.size() - 1;
L poz2 = b2.size() - 1;
while (poz1 >= 0 and poz2 >= 0) {
suma = dalej(d, b1[poz1] - 48 + b2[poz2] - 48) + suma;
if (poz1 >= 0) poz1--;
if (poz2 >= 0) poz2--;
}
while (poz1 >= 0) {
suma = dalej(d, b1[poz1--]-48) + suma;
}
while (poz2 >= 0) {
suma = dalej(d, b2[poz2--] - 48) + suma;
}
while(d) suma = dalej(d,0) + suma;
return suma;
}
bool czy_negacje(string b1, string b2) {
if (b1.size() != b2.size()) return false;
for (auto& e : b1) {
if (e == '0') e = '1';
else e = '0';
}
return (b1 == b2);
}
string wieksza(string b1, string b2) {
bez0(b1); bez0(b2);
if (b1.size() > b2.size()) return b1;
if (b2.size() > b1.size()) return b2;
if (b1 == b2) return b1; // takie same
for (size_t poz = 0; poz < b1.size(); poz++) {
if (b1[poz] > b2[poz]) return b1;
if (b2[poz] > b1[poz]) return b2;
}
}
26589ec988c76404b19a97e88c6609a5
2
126 C++ ZBIÓR ZADAŃ Z ROZWIĄZANIAMI
int main() {
setlocale(LC_ALL, "");
cout << dodaj("00101010111111", "0001111111") << endl << endl;
cout << dodaj("111", "1") << endl << endl;
Zadanie #2.74
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef long long int L;
typedef unsigned long long int UL;
//////////////////////////////////////////////////////
UL ostatni(UL N=100, int K = 3) {
vector<UL> v;
for (int i = 1; i <= N; i++) v.push_back(i);
UL pozycja = 0;
while (v.size() > 1) {
pozycja = (pozycja + K) % v.size();
v.erase(v.begin() + pozycja);
// zachowanie cykliczności przy skasowaniu ostatniego elementu
if (pozycja == v.size()) pozycja = 0;
}
return v[0];
}
int main() {
setlocale(LC_ALL, "");
UL o;
o = ostatni(100,3);
cout << "\nOstatnia ocalała liczba to: " << o << endl;
o = ostatni(6, 3);
cout << "\nOstatnia ocalała liczba to: " << o << endl;
o = ostatni(8, 3);
cout << "\nOstatnia ocalała liczba to: " << o << endl;
}
Zadanie #2.75
Nie, no jasne, pewnie…
26589ec988c76404b19a97e88c6609a5
2