Zadanie 1: Rekurencja - Matura z Informatyki 2026

Zadanie 1.1: Tabela wywołań rekurencyjnych A(m, n)

Mamy do uzupełnienia tabelę z kolumnami: m, n, liczba wywołań rekurencyjnych oraz same wywołania rekurencyjne funkcji A.
Jest to typowe zadanie maturalne - tylko zamiast pseudokodu mamy funkcję opisaną rekurencyjnym wzorem z warunkami. Możesz uderzyć w problem na dwa sposoby:
- Program lub arkusz - przepisujemy definicję A do dowolnego języka dozwolonego przy maturze i dla kolejnych par (m, n) uruchamiamy kod oraz odczytujemy wynik albo łańcuch wywołań. Szybkie uzupełnienie tabeli przy mniejszym wysiłku obliczeniowym.
- Ręczne prowadzenie wywołań - zamiast maszyny wywołujemy kolejne A(…,…) na kartce przy definicji z arkusza. Trwa dłużej, ale to właśnie ta droga pokazuje, dlaczego funkcja się tak zachowuje.
A to ma znaczenie, bo bardzo często w zadaniu 1.2 lub 1.3 pojawiają się pytania sprawdzające właśnie to zrozumienie działania funkcji.
Może przejdźmy więc drogą zrozumienia - krok po kroku, zamiast od razu przerzucać wszystko do programu.
Analiza przykładu z zadania
Przechodzimy więc do obliczeń. Zaczynamy od analizy przykładu, który jest już uzupełniony, żeby zrozumieć cały mechanizm.
Zaczynamy od m = 3 oraz n = 9.

Zerkamy na definicję funkcji: n jest równe 9, czyli nieparzyste, zatem podstawiamy do wzoru dla n nieparzystych. Wynikiem jest 2 · A(m, (n-1)/2) + m, czyli 2 · A(3, 4) + 3. To jest nasze pierwsze wywołanie rekurencyjne.
Nie wiemy jeszcze, jaką wartość ma wywołanie funkcji A z parametrami 3 i 4, zatem przechodzimy do kolejnego wywołania.

Tym razem n jest równe 4, czyli parzyste - podstawiamy do wzoru i wynikiem jest wywołanie A(6, 2).
Nadal nie znamy wyniku, więc przechodzimy do trzeciego wywołania.

Znów n jest parzyste - i otrzymujemy wywołanie funkcji A(12, 1). Tym razem n jest równe 1, zatem patrząc na definicję funkcji: rekurencja się kończy, ponieważ dla n = 1 wynikiem jest po prostu m, czyli 12.
Teraz moglibyśmy wrócić do góry i obliczyć wartość początkowego A(3, 9) - natomiast w tabeli trzeba tylko wypisać wywołania, więc jak widzimy, nasze wywołania się zgadzają.
A zamiast obliczać wynik, zerknijmy do treści zadania. W tych obliczeniach, które pominęliśmy, mamy dokładnie to, co obliczyliśmy, czyli 2 · A(12, 1) + 3, czyli 2 · 12 + 3, zatem wynikiem jest 27.
Kolejne wiersze tabeli
Przechodzimy do kolejnego wiersza tabeli, czyli do wartości m = 32 oraz n = 17. Tutaj w analogiczny sposób podstawiamy do wzoru i uzupełniamy tabelę.


A następnie dla m = 2⁵ i n = 2⁵ - również podstawiamy do wzoru.


Sprytne podejście do dużych wartości
Problem może się pojawić przy ostatnim wierszu, dla n = 2¹⁰⁰ + 1. Wywołań będzie tutaj sporo, więc trzeba podejść do tego sprytniej.


W pierwszym kroku n jest nieparzyste, ponieważ 2¹⁰⁰ + 1 jest liczbą nieparzystą. Zatem pierwsze wywołanie daje nam funkcję A(1, 2⁹⁹) - to jest nasz krok pierwszy.
Wszystkie następne wywołania będą miały n parzyste, ponieważ 2⁹⁹ jest potęgą dwójki, a każda potęga dwójki jest parzysta. Aby znaleźć liczbę tych wywołań, obliczamy logarytm dwójkowy z 2⁹⁹, co daje nam 99.
Czyli łącznie mamy: 1 wywołanie dla n nieparzystego plus 99 wywołań dla n parzystych - razem 100 wywołań.

Zadanie 1.2: Wartości funkcji A(m, n)

Mamy do uzupełnienia tabelę z wartościami funkcji A dla zadanych argumentów. Tym razem nie wystarczy wypisać samych wywołań - musimy doliczyć się do konkretnego wyniku, a w zapisie odpowiedzi możemy korzystać z operatorów mnożenia i potęgowania.
Pierwszy wiersz: A(1, 777)
Tutaj ponownie mamy dwa sposoby - albo możemy liczyć ręcznie, albo przepisać funkcję do programu i go uruchomić.
Zacznijmy od pierwszego sposobu, czyli ręcznego wypisywania kolejnych wywołań. Ten sposób jest zdecydowanie bardziej czasochłonny i podatny na błędy, ale za to daje nam pełne zrozumienie, jak funkcja działa.
Startujemy od funkcji A(1, 777) - n jest nieparzyste, więc wywołujemy funkcję A(m, (n-1)/2), czyli A(1, 388). Teraz n jest parzyste, więc wywołujemy funkcję A(2·m, n/2), czyli A(2, 194).
Kontynuujemy w analogiczny sposób dla kolejnych wywołań.

Dotarliśmy do funkcji A(64, 1) - jednak to nie koniec. Musimy teraz cofnąć się w tej rekurencji, aby uzyskać wynik dla początkowej funkcji A(1, 777).

Drugi wiersz: A(2 · 10⁹, 256 · 10⁹)
Gorzej sytuacja wygląda dla kolejnego przykładu - wywołań będzie tutaj całkiem sporo. Tutaj możemy zademonstrować drugi sposób, który pewnie najczęściej wybierają maturzyści pod presją czasu.
Zobaczmy przykładową realizację w języku Python, która po prostu jest odzwierciedleniem naszej definicji funkcji A.

Po uruchomieniu programu uzyskujemy 512 i 18 zer, co możemy zapisać jako 512 · 10¹⁸ - żeby na pewno nie pominąć żadnego zera.
Zadanie 1.3: Liczba wywołań i wyrażenie dla n

W tym podpunkcie musimy określić liczbę wywołań rekurencyjnych dla podanej wartości n oraz wartość drugiego argumentu, czyli n, w i-tym wywołaniu rekurencyjnym.
Pytanie, które mogłoby się na początku pojawić: co zrobić z pierwszym argumentem, czyli m? W końcu autor nigdzie go tutaj nie podaje. Zwróćmy jednak uwagę, że ten argument nie ma żadnego wpływu na liczbę wywołań rekurencyjnych.
Spójrzmy jeszcze raz na wzór: wszystkie warunki dotyczą n. Argument m ma jedynie wpływ na samą wartość wyniku, ale nie na liczbę wywołań.
Warto też zauważyć, że w tym zadaniu - już w podpunkcie 1.3 - musimy podać wzór na wartość n w i-tym wywołaniu rekurencyjnym. Tutaj nasz program w Pythonie już nam nie pomoże, bo nie poda nam wzoru ogólnego. I właśnie dlatego zrozumienie działania całej funkcji jest tutaj kluczowe - a mamy do zdobycia aż trzy punkty.

Jak znaleźć liczbę wywołań rekurencyjnych?
Musimy wykonywać dzielenie całkowite n przez 2:
- jeśli n jest nieparzyste, zmniejszamy je o 1 i dzielimy przez 2,
- jeśli n jest parzyste, dzielimy przez 2.
W obu przypadkach jest to dzielenie całkowite - inaczej można powiedzieć, że obliczamy ⌊n/2⌋, czyli podłogę z n przez 2.
Analiza przykładu z zadania
Wartość n wynosi 8. W następnym wywołaniu n będzie równe 4, potem 2, a następnie 1. Mamy zatem trzy wywołania rekurencyjne. Nasz sposób działa.

Jak znaleźć wzór na wartość n w i-tym wywołaniu? Trzeba skorzystać z faktu, że za każdym razem dzielimy przez 2. Liczba 8 jest potęgą dwójki - to 2³. Dzielenie 2ˣ przez 2 daje 2ˣ⁻¹. Stąd bierze się wzór: 2³⁻ⁱ, gdzie i jest numerem wywołania.

Kolejne wiersze tabeli
Dla n = 2ᵏ
Ile razy musimy podzielić 2ᵏ przez 2, aby uzyskać 1? Trzeba podzielić k razy - za każdym razem zmniejszamy wykładnik potęgi o 1. Wzór na wartość n w kolejnych wywołaniach wyznaczamy analogicznie jak poprzednio: 2ᵏ⁻ⁱ.


Dla n = 2ᵏ - 1
Tutaj sytuacja lekko się komplikuje - mamy nieparzyste n. Zobaczmy, co się stanie po pierwszym wywołaniu. Obliczamy: (2ᵏ - 1 - 1) / 2, co daje 2ᵏ⁻¹ - 1. Czyli po pierwszym wywołaniu rekurencyjnym n nadal jest nieparzyste. Widać, że w każdym kolejnym wywołaniu również będzie nieparzyste.
W każdym kroku wykładnik przy dwójce zmniejsza się o 1, aż dojdziemy do 2¹ - 1, czyli do 1. Musimy przejść od wykładnika k do 1, a zatem łącznie mamy k - 1 wywołań.

Ciekawostka: algorytm mnożenia metodą rosyjskich chłopów
Algorytm, który analizowaliśmy, to algorytm mnożenia metodą rosyjskich chłopów. Jak widać, nie jest to algorytm wymagany na maturze i autor nie podał tej nazwy w zadaniu - maturzysta nie mógł go więc znać z góry.
Co ciekawe jednak - i to mały plus dla nas - ten sam algorytm, w wersji nieco prostszej, bo iteracyjnej, pojawia się w naszym przygotowaniu już od lat. Jest to zadanie 3.2.4 w module trzecim, gdzie ten sam algorytm jest rozpisany w postaci listy kroków. Kto przerabiał go niedawno, mógł na to wpaść. Natomiast raczej niemożliwe jest, żeby znać na pamięć wszystkie zadania spośród 940, które aktualnie są dostępne na platformie.


Zadanie 2: Dodawanie - Matura z Informatyki 2026

Zadanie 2.1: Liczba przeniesień przy dodawaniu

Aby rozwiązać zadanie, wystarczy przeprowadzić klasyczne dodawanie pisemne i zliczyć przeniesienia. Pierwszy wiersz jest już uzupełniony, więc zaczynamy od drugiego.
Drugi wiersz: 88 765 + 11 111
Liczymy od końca, cyfra po cyfrze:

5 + 1 = 6 - brak przeniesienia,

6 + 1 = 7 - brak przeniesienia,

7 + 1 = 8 - brak przeniesienia,

8 + 1 = 9 - brak przeniesienia,

8 + 1 = 9 - brak przeniesienia.

Wynik to 0 przeniesień.
Trzeci wiersz: 456 789 + 222 222
Tutaj sytuacja jest ciekawsza:

9 + 2 = 11 - mamy pierwsze przeniesienie,

8 + 2 + 1 = 11 - mamy drugie przeniesienie,

7 + 2 + 1 = 10 - mamy trzecie przeniesienie,

6 + 2 + 1 = 9 - brak przeniesienia,

5 + 2 = 7 - brak przeniesienia,

4 + 2 = 6 - brak przeniesienia. Wynik to 3 przeniesienia.

Zadanie 2.2: Algorytm liczby przeniesień

Klucz do rozwiązania - modulo i dzielenie całkowite
W tym zadaniu będziemy używać:
- operatora modulo do wyciągania ostatniej cyfry liczby,
- operatora dzielenia całkowitego przez 10 do tego, żeby tej ostatniej cyfry się pozbyć i przejść do kolejnego rzędu wielkości.
Czyli absolutne podstawy z modułu pierwszego, z lekcji pierwszej. Prościej się nie dało.
Konstrukcja algorytmu
Skoro a i b mają tę samą liczbę cyfr, możemy od razu przejść do dodawania. Działając tak jak przy dodawaniu pisemnym, sumujemy osobno cyfry kolejnych rzędów: jedności, dziesiątek, setek i dalej w lewo.
Cyfry wyciągamy w pętli, dopóki a jest większe od 0. W każdej iteracji wyciągamy ostatnią cyfrę a i b za pomocą operatora modulo, a następnie dzielimy obie liczby całkowicie przez 10, żeby przejść do kolejnego rzędu.
Sumowanie cyfr to zwykłe dodawanie - należy tylko pamiętać o dodaniu przeniesienia z poprzedniej iteracji. Najgorszy przypadek to:
- 9 + 9 = 18 - czyli przeniesienie wynosi 1,
- 9 + 9 + 1 = 19 - czyli przeniesienie nadal wynosi co najwyżej 1.
Na koniec sprawdzamy, czy pojawiło się przeniesienie.
Tak prezentuje się realizacja w języku Python:

Zadanie 3: Prawdziwość zdań o tabelach Osoby i Samochody - Matura z Informatyki 2026

W zadaniu 3 mamy dwie tabele: jedną z osobami i drugą z samochodami. Interesuje nas zapytanie, które łączy te tabele i dla każdej osoby liczy, ile samochodów jest z nią powiązanych.
Wykorzystujemy połączenie LEFT JOIN, więc przechodzimy przez wszystkie osoby, nawet te, które nie mają żadnego samochodu. Następnie grupujemy wynik według Id_Osoby, dzięki czemu dla każdej osoby otrzymujemy jeden wiersz. W tym wierszu funkcja COUNT zlicza wszystkie samochody przypisane do tej osoby - nie różne marki, tylko wszystkie rekordy z tabeli Samochody, które mają jej Id_Osoby.
Przechodzimy więc przez osoby po kolei:
- Janusz Warecki ma trzy samochody, więc w polu
Liczbaotrzymamy 3. - Wojciech Namyslo ma dwa samochody, więc otrzymamy 2.
- Ewelina Nowicka również ma dwa samochody, więc wynik to 2.
- Beata Kosińska nie ma żadnego samochodu, więc w jej wierszu pojawi się 0.
Widzimy więc wyraźnie, że zapytanie nie liczy różnych marek, tylko wszystkie samochody przypisane do właściciela.
Na tej podstawie oceniamy zdania:
- „Dla każdego właściciela otrzymamy informację, ile ma różnych marek pojazdów.” - fałsz. Nie liczymy różnych marek, tylko wszystkie samochody.
- „Dla każdego właściciela otrzymamy informację, ile ma pojazdów.” - prawda, dokładnie to robi zapytanie.
- „Dla Eweliny Nowickiej w polu Liczba otrzymamy wynik 3.” - fałsz. Ewelina ma dwa samochody, a nie trzy.
- „Dla Beaty Kosińskiej w polu Liczba otrzymamy wynik 0.” - prawda. Beata nie ma żadnego samochodu, więc wynik to 0.
W efekcie poprawny zestaw odpowiedzi to: F, P, F, P.
Zadanie 4: Pary słów - Matura z Informatyki 2026

Zadanie 4.1: Sumy kodów ASCII par słów

Wyjątkowo proste zadanie - kody ASCII to znowu jedna z pierwszych lekcji.
Co musimy zrobić?
Stworzyć dedykowaną funkcję, która obliczy sumę kodów ASCII dla podanego słowa - szybkie i super proste. Używamy oczywiście funkcji ord, zamieniającej znaki na kody ASCII. Następnie analizujemy wyniki w prostych pętlach i znajdujemy parę z najmniejszą sumą oraz parę z największą różnicą.
Tworzymy funkcję oblicz_sume_ascii, której zadaniem jest obliczenie sumy kodów ASCII wszystkich znaków w danym słowie. Wewnątrz funkcji ustawiamy zmienną suma na 0, a następnie przechodzimy pętlą po każdym znaku w słowie. Dla każdego znaku używamy funkcji ord, która zwraca jego kod ASCII, i dodajemy tę wartość do zmiennej suma. Na końcu funkcja zwraca obliczoną sumę.
Następnie implementujemy dwie funkcje rozwiązujące podpunkty a) i b).
Podpunkt a)
Tworzymy funkcję znajdz_pare_z_najmniejsza_suma_ascii. To ona odpowiada za znalezienie pary słów, dla której suma kodów ASCII jest najmniejsza.
Na początku ustawiamy zmienną najmniejsza_suma na bardzo dużą liczbę, na przykład 10⁹, żeby każda poprawnie obliczona suma mogła ją zastąpić. Tworzymy też dwie zmienne: najlepsze_slowo_1 i najlepsze_slowo_2, w których będziemy zapisywać aktualnie najlepszą parę słów.
Przechodzimy pętlą po wszystkich parach słów zapisanych w liście. Dla każdej pary osobno obliczamy sumę kodów ASCII pierwszego i drugiego słowa, korzystając z wcześniej napisanej funkcji, i je do siebie dodajemy.
Jeżeli obliczona suma jest mniejsza niż dotychczasowa wartość zmiennej najmniejsza_suma, aktualizujemy wszystkie trzy informacje: najmniejszą sumę oraz oba słowa, które tę sumę dały. Po sprawdzeniu wszystkich par funkcja zwraca najlepszą znalezioną parę słów oraz najmniejszą sumę.
Podpunkt b)
Tworzymy funkcję znajdz_pare_z_najwieksza_roznica_ascii, która działa bardzo podobnie do funkcji z podpunktu a).
Ustawiamy zmienną najwieksza_roznica na -1, dzięki temu każda wartość bezwzględna różnicy będzie mogła ją zastąpić. Ponownie tworzymy zmienne najlepsze_slowo_1 i najlepsze_slowo_2, w których będziemy zapisywać aktualnie najlepszą parę słów.
Przechodzimy pętlą po wszystkich parach słów zapisanych w liście. Dla każdej pary osobno obliczamy sumę kodów ASCII pierwszego i drugiego słowa, korzystając z wcześniej napisanej funkcji. Następnie obliczamy wartość bezwzględną różnicy tych sum za pomocą funkcji abs.
Jeżeli obliczona różnica jest większa niż dotychczasowa wartość zmiennej najwieksza_roznica, aktualizujemy wszystkie trzy informacje: największą różnicę oraz oba słowa, które tę różnicę dały. Po sprawdzeniu wszystkich par funkcja zwraca najlepszą znalezioną parę słów oraz największą różnicę.
Rozwiązanie - zadanie 4.1 (Python):
Zadanie 4.2: Wspólne wystąpienia liter

Naszym celem jest znalezienie par słów z największą liczbą wspólnych liter. Wspólne litery według wzoru to mniejsza z dwóch wartości: liczby wystąpień danej litery w słowie s1 i liczby wystąpień tej samej litery w słowie s2.
W tym zadaniu mamy dwa podpunkty. Podpunkt a) ogranicza wzór do jednej litery - b - i każe wypisać wszystkie pary z największym wynikiem. Podpunkt b) to to samo polecenie co zadanie 3.2 z formuły 2023: para z największą sumą wspólnych wystąpień po całym alfabecie.
Podpunkt a)
Liczymy wyłącznie literę b. Tworzymy funkcję wspolna_liczba_wystapien_b, która dla dwóch słów wywołuje count("b") na każdym z nich i zwraca min tych dwóch liczb - czyli W(b, s1, s2) z treści.
Następnie funkcja znajdz_pary_z_najwieksza_liczba_wspolnych_b przegląda wszystkie wczytane z pliku pary. Na starcie ustawiamy zmienną najwieksza_liczba_wspolnych_b na -1, a najlepsze_pary na pustą listę. Przechodzimy pętlą po wszystkich parach zapisanych w liście pary_slow i dla każdej z nich wywołujemy funkcję wspolna_liczba_wystapien_b. Porównujemy wynik funkcji z dotychczasowym maksimum:
- jeśli jest większy - ustawiamy nowe maksimum (
najwieksza_liczba_wspolnych_b) i zaczynamy listę od nowa od tej jednej pary (najlepsze_pary = [[s1, s2]]), - jeśli jest równy - dopisujemy parę do listy, bo polecenie każe wypisać wszystkie takie pary.
Po przejściu pliku funkcja zwraca listę par, nie pojedynczy wynik. W kluczu CKE są dwie pary - program musi więc umieć zebrać remis, a nie zatrzymać się na pierwszej trafionej parze.
Podpunkt b)
Strategia rozwiązania
Czyli co będziemy robić: dla każdej litery alfabetu policzymy liczbę jej wystąpień w obu słowach, wybierzemy mniejszą z tych dwóch wartości i dodamy ją do ogólnej sumy.
Pomocne będzie operowanie na zmiennej przechowującej cały alfabet lub szybkie działanie na kodach ASCII. Przyda się też metoda count do policzenia wystąpień - choć równie dobrze możemy napisać własną funkcję zliczającą za pomocą pętli.

Najpierw tworzymy funkcję policz_wspolne_litery, która przyjmuje dwa słowa: slowo_1 i slowo_2. Wewnątrz funkcji ustawiamy zmienną liczba_wspolnych_liter na 0 - będzie ona przechowywać łączną liczbę wspólnych liter dla danej pary.
Następnie tworzymy zmienną alfabet, w której zapisujemy wszystkie małe litery alfabetu angielskiego. Dzięki temu możemy łatwo przejść pętlą po każdej możliwej literze. Dla każdej litery sprawdzamy, ile razy występuje ona w pierwszym słowie i ile razy w drugim, korzystając z metody count.
Jeżeli na przykład litera występuje 3 razy w pierwszym słowie i 5 razy w drugim, to wspólne są tylko 3 wystąpienia. Dlatego do wyniku dodajemy mniejszą z tych dwóch wartości, używając funkcji min. Po sprawdzeniu wszystkich liter alfabetu funkcja zwraca łączną liczbę wspólnych liter dla podanej pary słów.
Następnie przechodzimy do kolejnej funkcji: znajdz_pare_z_najwieksza_liczba_wspolnych_liter. To ona odpowiada za znalezienie najlepszej pary w całym pliku.
Na początku ustawiamy zmienną najwieksza_liczba_wspolnych_liter na -1, aby pierwsza sprawdzana para mogła od razu zostać zapisana jako aktualnie najlepsza. Tworzymy też zmienne najlepsze_slowo_1 i najlepsze_slowo_2, w których będziemy przechowywać słowa z najlepszej dotychczas znalezionej pary.
Przechodzimy pętlą po wszystkich parach zapisanych w liście pary_slow. Dla każdej pary wywołujemy funkcję policz_wspolne_litery, która zwraca liczbę wspólnych liter dla słów s1 i s2. Jeżeli ta wartość jest większa niż dotychczasowa największa, aktualizujemy wynik i zapamiętujemy oba słowa.
Po zakończeniu pętli funkcja zwraca dwa słowa z pary o największej sumie.
Na koniec mamy wczytanie danych z pliku tekstowego. Najpierw zbieramy listę par do podpunktu a), potem parę do podpunktu b), i wypisujemy wynik z nagłówkami a) oraz b).
Rozwiązanie - zadanie 4.2 (Python):
Zadanie 4.3: Prefiksosufiksy par słów

Najpierw musimy dobrze zrozumieć, czym jest prefiksosufiks. Interesuje nas sytuacja, w której początek jednego słowa jest taki sam jak koniec drugiego słowa.
Dla każdej pary słów sprawdzamy dwa możliwe warianty:
- Wariant pierwszy - bierzemy prefiks, czyli początek pierwszego słowa, i porównujemy go z sufiksem, czyli końcem drugiego słowa.
- Wariant drugi - działa odwrotnie: bierzemy początek drugiego słowa i porównujemy go z końcem pierwszego słowa.
Naszym celem jest znalezienie najdłuższego takiego dopasowania spośród obu wariantów.

Strategia rozwiązania
Jak to zrealizować? Rozpiszmy to po kolei:
- Po pierwsze - szukamy jednego najdłuższego dopasowania.
- Po drugie - wyznaczamy minimum z długości obu słów, bo nie ma sensu szukać dopasowań dłuższych niż krótsze z nich.
- Po trzecie - pętlę najlepiej zacząć od największej możliwej długości i schodzić w dół. Dzięki temu pierwsze znalezione dopasowanie będzie od razu najdłuższe.
- Po czwarte - wybieramy maksymalny wynik spośród obu wariantów.
- Po piąte - zapisujemy tylko te pary, dla których wynik wynosi co najmniej 5 znaków.
Implementacja
Tworzymy funkcję najdluzsze_dopasowanie. Przyjmuje ona dwa słowa: jedno traktujemy jako źródło prefiksu (czyli początku), a drugie jako źródło sufiksu (czyli końca).
Na początku obliczamy maksymalną możliwą długość dopasowania. Nie ma sensu sprawdzać fragmentu dłuższego niż krótsze z tych dwóch słów, dlatego bierzemy minimum z ich długości. Następnie przechodzimy pętlą od tej największej możliwej długości w dół do jedynki. W każdej iteracji porównujemy prefiks i sufiks - jeżeli są sobie równe, znaleźliśmy dopasowanie i od razu zwracamy jego długość. Jeżeli pętla zakończy się bez żadnego dopasowania, funkcja zwraca 0.
Przechodzimy do funkcji znajdz_pary_z_dopasowaniem. Ta funkcja analizuje wszystkie pary słów z pliku. Dla każdej pary, czyli dla słów s1 i s2, liczymy dwa dopasowania:
- pierwsze sprawdza, jak długi prefiks słowa
s1pasuje do sufiksu słowas2, - drugie sprawdza sytuację odwrotną.
Następnie wybieramy większą z tych dwóch wartości. Jeżeli najdłuższe znalezione dopasowanie ma co najmniej 5 znaków, dodajemy tę parę do wyników.
Na końcu wczytujemy dane z pliku pary.txt i uruchamiamy funkcję.
Rozwiązanie - zadanie 4.3 (Python):
Tym samym zakończyliśmy zadanie 4. Możemy umieścić nasze odpowiedzi w pliku wyniki4.txt i przejść do kolejnego zadania.

Zadanie 5: Staw - Matura z Informatyki 2026

Zadanie 5.1: Średnie temperatury miesięcy i wykres

Jak każde zadanie z arkusza kalkulacyjnego rozpoczynamy od wczytania danych. Wchodzimy w zakładkę „Dane” i wybieramy „Z pliku tekstowego/CSV”. Excel powinien sam rozpoznać odpowiedni format, ale warto upewnić się, że ogranicznikiem jest tabulator, a daty są poprawnie wykryte. Klikamy „Załaduj” i mamy bazę do pracy.

Aby utworzyć zestawienie miesięczne, musimy najpierw wyciągnąć miesiąc z daty. Użyjemy do tego prostej funkcji MIESIĄC() z naszą datą jako parametrem.

Teraz czas na główne obliczenia. Na szczęście Excel ma zaawansowaną funkcję ŚREDNIA.WARUNKÓW(). Dzięki niej nie musimy pisać zagnieżdżonych funkcji JEŻELI() - wystarczy wskazać trzy elementy: z czego liczymy średnią, gdzie szukamy warunku i jaki to konkretnie warunek.

Jako pierwszy argument podajemy zakres temperatur, z których liczymy średnią. Drugi to nasza nowa kolumna z miesiącami, a trzeci to konkretny numer miesiąca, dla którego w danym wierszu robimy obliczenie. Pamiętajmy też o zaokrągleniu w formule do jednego miejsca po przecinku.

Gdy zestawienie jest gotowe, zaznaczamy naszą tabelę, wchodzimy w zakładkę „Wstawianie” i w sekcji z wykresami wybieramy klasyczny wykres kolumnowy 2D.

Uwaga! Samo wstawienie wykresu to dopiero połowa sukcesu. Wytyczne w kluczu CKE wskazują wprost, że egzaminator nie może przyznać maksymalnej liczby punktów za zadanie z wykresem, jeśli brakuje odpowiedniego formatowania. Zadbaj o czytelne formatowanie, czyli dodaj odpowiedni tytuł wskazany w zadaniu, opisy osi oraz legendę (jeśli jest wymagana). Brak tych elementów to częsty błąd, który prowadzi do niepotrzebnej straty punktów.
Co też ciekawe, nawet jeśli dane przedstawione na wykresie byłyby niepoprawne, a formatowanie wykresu będzie dobrze zrobione, otrzymasz punkty właśnie za formatowanie wykresu.

Jak to zrobić szybko i sprawnie? Zielony plusik w prawym górnym rogu wykresu pozwoli wybrać jego elementy. W tym zadaniu potrzebujemy tytułów osi i wykresu oraz etykiet danych.
Zmiana etykiet osi jest trochę bardziej wymagająca. Najpierw trzeba utworzyć je w osobnej kolumnie, a następnie w zakładce „Projekt wykresu” wybrać „Zaznacz dane”. Klikamy „Edytuj” i w okienku po prawej stronie zaznaczamy kolumnę z nazwami miesięcy.

Tak przygotowany wykres zapewni Ci maksymalną liczbę punktów za to zadanie.

Zadanie 5.2: Najdłuższy ciąg dni bez opadów

Zadanie wymaga od nas trochę więcej logiki niż poprzednie. Musimy policzyć spójne podciągi, ale z jednym ważnym zastrzeżeniem - licznik musi się resetować nie tylko wtedy, gdy spadnie deszcz, ale również wtedy, gdy zmieni się miesiąc.
Rozwiązanie warto zacząć od kolumny pomocniczej „Czy padało?”. Używamy tu prostej funkcji JEŻELI(), która sprawdzi, czy wartość w kolumnie „Opady” jest równa 0. Jeśli tak - funkcja zwróci 0, co oznacza brak opadów. W przeciwnym wypadku otrzymamy 1, czyli potwierdzenie, że tego dnia padało.

Zanim przejdziemy do pisania głównej formuły na długość ciągu, spójrzmy na schemat logiczny. Musimy sprawdzić dwa kluczowe warunki: czy zmienił się miesiąc oraz czy w ogóle padało. Jeśli miesiąc jest nowy, sprawdzamy tylko bieżący dzień. Jeśli jednak jesteśmy w tym samym miesiącu, sprawdzamy, czy możemy wydłużyć wczorajszą passę bez deszczu o 1, czy musimy zresetować licznik do zera z powodu opadów.

W praktyce realizujemy to za pomocą zagnieżdżonej funkcji =JEŻELI(). Najpierw sprawdzamy zmianę miesiąca. Jeśli miesiąc się zmienił, sprawdzamy, czy padało. Jeżeli nie, startujemy od 1. Jeśli tak - od 0. Natomiast jeżeli to ten sam miesiąc, sprawdzamy naszą kolumnę pomocniczą i gdy mamy tam 0, do wyniku z poprzedniego dnia dodajemy 1. W przeciwnym wypadku zostawiamy 0.

Mając tak przygotowaną kolumnę z ciągami, wystarczy wyciągnąć wartość maksymalną dla każdego miesiąca. Ponownie z pomocą przychodzi funkcja warunkowa - tym razem MAKS.WARUNKÓW(). Jako zakres wyszukiwania podajemy nasze wyliczone ciągi, jako kryterium - zakres z miesiącami, a jako wartość warunku - numer badanego miesiąca.


Zadanie 5.3: Dni z tempem rozrostu 1% i 2%

W zadaniu musimy dla każdego dnia określić tempo wzrostu rzęsy oraz podać liczbę dni, w których wynosiło ono odpowiednio 1% i 2%.
Przeanalizujmy najpierw regułę obliczania tempa wzrostu na schemacie:

Można wywnioskować, że do wyznaczenia tempa wzrostu rzęsy wystarczy nam rozbudowana funkcja JEŻELI(). Najpierw sprawdzamy, czy opady są nie większe niż 5 mm. Jeżeli tak, w kolejnym kroku weryfikujemy, czy temperatura mieści się w przedziale odpowiadającym wzrostowi 1% lub 2%.

Gdy mamy gotową kolumnę z tempem wzrostu dla każdego dnia, używamy funkcji LICZ.JEŻELI(), aby policzyć, dla ilu dni tempo wynosiło 1%, a dla ilu 2%.

Zadanie 5.4: Pierwszy dzień z rzęsą powyżej 75%

Przechodzimy do najciekawszej części z arkusza kalkulacyjnego - symulacji.
Budowę symulacji zaczynamy od wygenerowania osi czasu. Wpisujemy datę początkową 01.03.2023 w komórkę A2 i przeciągamy ją w dół. Aby objąć cały badany okres 184 dni, musimy dojechać aż do komórki A185 - Excel automatycznie uzupełni daty pomiędzy.

Bardzo pomocna będzie kolumna z dniem tygodnia. Dlaczego? Bo właściciel odławia rzęsę tylko w piątki. Używamy funkcji DZIEŃ.TYG(). Parametr 2 jest tu bardzo ważny - dzięki niemu poniedziałek to 1, a nasz kluczowy piątek to 5. To znacznie ułatwi pisanie warunku ubytku.

Przechodzimy do liczenia powierzchni zarośnięcia stawu przez rzęsę. Z treści zadania wiemy, że 1 marca rano staw był zarośnięty w 20%, czyli 20% z 10 000 m² równa się 2000 m². Na razie zostawiamy stan rano, ponieważ zależy on od reszty symulacji.

Sercem naszego modelu będzie formuła na ubytek rzęsy w ciągu dnia. Wiemy, że 80 amurów zjada łącznie 20 m² (80 razy wydajność jednego amura, czyli 0,25 m²). Do tego dochodzą piątkowe odłowienia właściciela. Jeśli w kolumnie z dniem tygodnia mamy piątkę, Excel odejmie łącznie 80 m², w pozostałe dni tylko 20 m².

Stan wieczorem to po prostu różnica stanu z rana i ubytku, który właśnie wyliczyliśmy.
Teraz musimy wrócić do stanu rano kolejnego dnia. Co działo się w nocy? Rzęsa rosła. Stan rano to wczorajszy stan wieczorem pomnożony przez współczynnik wzrostu. Skoro przyrost wynosi 1,75%, to mnożymy przez 1,0175. Pamiętajmy, by tę formułę wpisać dopiero od kolejnego wiersza (czyli 2 marca), bo 1 marca mamy podaną wartość startową 2000 m².

Ostatni element to przeliczenie powierzchni na procenty. Dzielimy aktualny stan rano przez całkowitą powierzchnię stawu, czyli przez 10 000. Formatujemy komórkę jako procentową i możemy przystąpić do sprawdzania wyników.

Szybka weryfikacja ze wskazówką w treści zadania: 30 kwietnia rano mamy 25,79% - idealnie, nasz model działa bezbłędnie. Teraz szukamy momentu, w którym wartość przekracza 75%. Dzieje się to 14 sierpnia 2023 roku.

Zadanie 5.5: Najmniejsza liczba amurów białych

Z przygotowanymi formułami z poprzedniego podpunktu to zadanie to formalność. Wystarczy manipulować liczbą amurów w naszej formule z ubytkiem i sprawdzać wartość maksymalną powierzchni rzęsy. Zmodyfikujmy formułę liczącą ubytek tak, aby liczba amurów była pobierana z konkretnej, pojedynczej komórki - dzięki temu w ułamek sekundy zmieniamy kolejne warianty.

Zanim zaczniemy testować różne wartości, dopiszmy jeszcze formułę, która szybko sprawdzi najwyższy zanotowany procent zarośnięcia w całym badanym okresie. Teraz zostaje już tylko podstawienie liczby, która sprawi, że MAKS() zwróci mniej niż 50%, ale po zmniejszeniu o jeden otrzymamy wartość przekraczającą limit:
- 80 amurów → 95,81%,
- 100 amurów → zarośnięcie spada poniżej 30%,
- 93 amury → wciąż 52,50%,
- 94 amury → 49,17% - zmniejszenie liczby amurów wyprowadza nas już poza limit 50%.

Na końcu możemy jeszcze rzucić okiem, jak wyglądałby wypełniony plik wyniki5.txt z odpowiedziami do zadania. I gotowe! Wszystkie zadania dotyczące arkusza kalkulacyjnego mamy wykonane.

Zadanie 6: Sieć sklepów - Matura z Informatyki 2026

Zadanie należało zacząć od wczytania danych z plików tekstowych dołączonych do arkusza. Są to trzy zbiory rekordów: klienci.txt, transakcje.txt oraz opis_transakcji.txt - zwykle każdy importujemy do osobnej tabeli (np. Klienci, Transakcje, Opis_transakcji).
- Uwaga 1 (data w transakcjach). Przy imporcie
transakcje.txtwarto upewnić się, że pole z datą ma właściwy typ (Data i godzina) oraz że daty są odczytywane w układzie DMR (dzień-miesiąc-rok), zgodnie z arkuszem. W większości przypadków Access ustawi to poprawnie w kreatorze, ale ten krok warto zweryfikować przy pierwszym imporcie (także w zapisanej specyfikacji). - Uwaga 2 (`opis_transakcji`). W tej tabeli pole
IdTransakcjipowtarza się (wiele wierszy na jedną transakcję), więc nie nadaje się na klucz podstawowy - przy imporcie nie wolno zakładać, że jest unikalne między wierszamiOpis_transakcji.


Po wczytaniu danych trzeba było jeszcze powiązać tabele relacjami zgodnie ze schematem z arkusza: między innymi Klienci → Transakcje po IdKlienta oraz Transakcje → Opis_transakcji po IdTransakcji (typowe powiązania jeden-do-wielu). Poniżej przykład takiego układu w oknie relacji Access.

Zadanie 6.1: Klient z największą liczbą transakcji

W zadaniu należy znaleźć imię i nazwisko klienta, który w rozpatrywanym okresie zrealizował łącznie najwięcej transakcji - czyli takiego, dla kogo w tabeli Transakcje jest najwięcej wierszy (największa liczba IdTransakcji przypiętych do danego IdKlienta). Wystarczą tu dwie tabele: Klienci i Transakcje (powiązane po IdKlienta), żeby złączyć dane biograficzne z liczbą zapisów o zakupach.
W kwerendzie stosujemy Grupuj według m.in. po IdKlienta, Imie i Nazwisko, a dla IdTransakcji funkcję Policz - dzięki temu dla każdego klienta dostajemy łączną liczbę transakcji. Następnie ustawiamy sortowanie malejąco według policzonych transakcji i tak dobieramy odpowiedź: interesuje nas pierwszy wiersz (najwyższy licznik).

Zadanie 6.2: Kobiety i mężczyźni bez zakupów

Z technicznego punktu widzenia szukamy identyfikatorów z tabeli Klienci, dla których w tabeli Transakcje nie ma ani jednego wiersza - czyli to naturalne pole do konstrukcji kwerendy wyszukującej niepasujące dane (porównanie Klienci z Transakcje po IdKlienta).
Jak utworzyć kwerendę wyszukującą niepasujące dane?
W oknie Nowa kwerenda wybieramy Kreator kwerend wyszukujących niepasujące dane - prowadzi on przez wybór tabeli „źródłowej” i tabeli porównawczej oraz przez dopasowanie klucza.

Interesują nas klienci bez żadnej transakcji - jako pierwszą wskazujemy więc tabelę Klienci: to z niej pochodzą rekordy, które mają trafić do wyniku kwerendy pomocniczej (o ile nie mają dopasowania po drugiej stronie).

Tabelą z pokrewnymi rekordami jest Transakcje - bo to tam szukamy dowodu, że dany klient cokolwiek kupił.

W obu tabelach łączymy się po IdKlienta. W wyniku kreatora chcemy zobaczyć co najmniej IdKlienta oraz Plec, żeby później móc zliczyć łączną liczbę kobiet (K) oraz mężczyzn (M).


Po zakończeniu kreatora zapisujemy kwerendę pomocniczą - w arkuszu widać listę klientów bez wpisów w Transakcje (np. widok zadanie_6_2_pom z polami IdKlienta i Plec).

Na podstawie tego zestawienia tworzymy kwerendę wynikową: Grupuj według Plec, a IdKlienta agregujemy przez Policz, żeby otrzymać liczbę kobiet i mężczyzn wśród klientów bez żadnego zakupu.
W arkuszu końcowej kwerendy pojawiają się dwa wiersze z płcią i liczbą osób. Łączna liczba kobiet (K) to 689, a łączna liczba mężczyzn (M) to 651.

Zadanie 6.3: Klienci w kasach samoobsługowych

Do wyliczenia odpowiedzi z polecenia trzeba najpierw wydzielić w bazie transakcje „z kasy samoobsługowej”. Zgodnie z opisem w arkuszu oznacza to brak przypisanego sprzedawcy: w wierszu tabeli Transakcje pole IdSprzedawcy jest puste, więc w kwerendzie ten przypadek filtrujemy warunkiem Is Null (wartość NULL = brak IdSprzedawcy).
Najpierw budujemy kwerendę pomocniczą, która wypisuje unikalnych klientów (IdKlienta), którzy dokonywali transakcji w kasie samoobsługowej: łączymy Transakcje z tabelą Klienci (relacja po IdKlienta), filtrujemy po pustym IdSprzedawcy (Is Null) i dzięki opcji Grupuj według usuwamy duplikaty klientów.

W kolejnej kwerendzie (wynikowej) korzystamy z kwerendy stworzonej chwilę temu. Aby policzyć wszystkich klientów, używamy funkcji Policz dla pola IdKlienta - i podpunkt jest gotowy.

Zadanie 6.4: Sklepy i kwoty kas samoobsługowych

Podobnie jak w poprzednim podpunkcie, transakcje z kasy samoobsługowej filtrujemy w tabeli Transakcje warunkiem Is Null na IdSprzedawcy.
Sensownie jest rozbić pracę na kilka kwerend. Najpierw budujemy kwerendę pomocniczą, która wypisuje unikalne sklepy (IdSklepu), w których w ogóle była transakcja samoobsługowa: łączymy Transakcje z Opis_transakcji (relacja po IdTransakcji), znów ograniczamy się do pustego IdSprzedawcy i przez Grupuj według usuwamy duplikaty sklepów.

Do odpowiedzi na pierwsze pytanie, czyli o liczbę sklepów, w osobnej kwerendzie wynikowej liczymy rekordy z zestawienia pomocniczego: Policz na IdSklepu względem wcześniej zapisanej listy (np. zadanie_6_4_unikalne_sklepy). Otrzymaliśmy wartość 28.

Drugą wartość, czyli łączną zapłatę, liczymy w kolejnej kwerendzie. Znów łączymy Transakcje z Opis_transakcji, ograniczamy się do transakcji z pustym IdSprzedawcy, a kwotę z pozycji zakupu wyprowadzamy jako iloczyn Cena i Liczba. Sumujemy te wartości po wszystkich liniach przypisanych do takich transakcji. Otrzymaliśmy wartość 19443,29.

Zadanie 6.5: Sprzedawca w największej liczbie sklepów

Pracę nad tym podpunktem zaczynamy od kwerendy pomocniczej, która wypisuje unikalne kombinacje sprzedawca - sklep - miesiąc. Miesiąc wyciągamy z daty funkcją Month([DataTransakcji]), a deduplikację zapewniamy Grupuj według po IdSprzedawcy, IdSklepu i tak zdefiniowanym polu Miesiac. Transakcje z kas samoobsługowych (puste IdSprzedawcy) odrzucamy warunkiem Is Not Null na IdSprzedawcy.

W kolejnej kwerendzie pomocniczej pracujemy na powyższym zestawieniu (np. zadanie_6_5_pom): Grupuj według IdSprzedawcy i Miesiac, a dla IdSklepu stosujemy Policz - dzięki temu dla każdej pary sprzedawca - miesiąc dostajemy liczbę różnych sklepów, w których ten sprzedawca obsłużył klientów. Wynik sortujemy malejąco i w zakładce Zwróć wpisujemy 1.

Zgodnie z poleceniem w odpowiedzi do podpunktu a) trzeba podać nazwę miesiąca. Przekonwertujemy numer miesiąca na jego nazwę w kolejnej kwerendzie, ponieważ ta kwerenda przyda nam się jeszcze do realizacji podpunktu b).

W kwerendzie wynikowej do podpunktu b) łączymy relacją tabelę Transakcje i kwerendę pomocniczą nr 2 (np. zadanie_6_5_sprzedawca_miesiac) po IdSprzedawcy. Następnie grupujemy po IdSklepu, a dla pola IdTransakcji stosujemy funkcję Policz. Wyciągamy z pola DataTransakcji miesiące za pomocą funkcji Month(), a w kryteriach odwołujemy się do pola Miesiac z kwerendy pomocniczej, aby ograniczyć zestawienie wyłącznie do stycznia. Teraz mamy oba podpunkty zadania 6.5 gotowe.

To był ostatni podpunkt zadania 6, więc po wpisaniu odpowiedzi z 6.1-6.5 możemy zerknąć, jak wygląda przykładowa zawartość pliku wyniki6.txt.
