Maj 2024

Matura Rozszerzona Informatyka 2024 Maj
Rozwiązania krok po kroku

Egzamin maturalny z informatyki na poziomie rozszerzonym to przekrojowy sprawdzian umiejętności cyfrowych i logicznego myślenia. Arkusz CKE obejmuje szerokie spektrum zagadnień – od projektowania i analizy algorytmów oraz sprawnego programowania w językach wysokiego poziomu, przez techniczne aspekty działania systemów i bezpieczeństwa danych, aż po zaawansowane operacje w arkuszach kalkulacyjnych i relacyjnych bazach danych. To kompleksowa weryfikacja przygotowania do dalszego kształcenia na kierunkach technologicznych.

Czas: 210 min
📄 Pobierz Arkusz PDF

Matura Rozszerzona Informatyka Maj 2024

0
Zadanie 1.

Zadanie 1. Plansza

Dana jest prostokątna plansza złożona z nn wierszy i mm kolumn zawierająca nmn \cdot m pól. Wiersze są ponumerowane od góry kolejnymi liczbami 1, 2, ..., nn, natomiast kolumny od lewej do prawej kolejnymi liczbami 1, 2, ..., mm. Każde pole jest albo białe, albo czarne.

Planszę możemy opisać jako tablicę dwuwymiarową A[1..n][1..m]A[1..n][1..m], w której A[i][j]=0A[i][j] = 0, jeśli pole w ii-tym wierszu i jj-tej kolumnie jest czarne, natomiast A[i][j]=1A[i][j] = 1, jeśli to pole jest białe. Pola w lewym górnym rogu oraz prawym dolnym rogu zawsze są białe (czyli A[1][1]=1A[1][1] = 1 oraz A[n][m]=1A[n][m] = 1).

Rozważmy następujący algorytm, w którym jest wykorzystywana pomocnicza tablica P[1..n][1..m]P[1..n][1..m], przyjmująca wartości logiczne (PRAWDA albo FAŁSZ).

Specyfikacja:
Dane:
  • nn, mm – liczby całkowite dodatnie, wymiary planszy
  • A[1..n][1..m]A[1..n][1..m] – opis planszy
Wynik:
  • PRAWDA albo FAŁSZ
P[1][1] <- PRAWDA
dla i = 1, 2, ..., n wykonuj
  dla j = 1, 2, ..., m wykonuj
      jeżeli A[i][j] = 0
          P[i][j] <- FAŁSZ
      w przeciwnym przypadku
          jeżeli i = 1 oraz j ≠ 1
              P[i][j] <- P[i][j - 1]
          jeżeli i ≠ 1 oraz j = 1
              P[i][j] <- P[i - 1][j]
          jeżeli i ≠ 1 oraz j ≠ 1
              P[i][j] <- P[i][j - 1] lub P[i - 1][j]
podaj wynik P[n][m]
💡 Pokaż rozwiązanie krok po kroku
  • 1

    Analiza działania algorytmu

    Zanim przejdziemy do konkretnych podpunktów, warto zrozumieć, co robi przedstawiony pseudokod. Jest to klasyczny algorytm programowania dynamicznego.

    • Tablica P[i][j]P[i][j] przechowuje informację, czy da się dojść z pola startowego (1,1)(1,1) do pola (i,j)(i,j).
    • Zgodnie z kodem, jeśli pole jest czarne (A[i][j]=0A[i][j] = 0), od razu wpisujemy tam FAŁSZ (nie da się na nie wejść).
    • Jeśli jesteśmy w pierwszym wierszu (i = 1), możemy przyjść tam tylko z lewej strony (z komórki [i][j - 1]).
    • Jeśli jesteśmy w pierwszej kolumnie (j = 1), możemy przyjść tam tylko z góry (z komórki [i - 1][j]).
    • W każdym innym przypadku (środek planszy), na dane pole możemy dojść albo z góry, albo z lewej strony. Stąd instrukcja lub.

    Wniosek: Algorytm sprawdza, czy istnieje jakakolwiek ścieżka z lewego górnego rogu do prawego dolnego rogu, poruszając się wyłącznie w prawo i w dół po białych polach.

Matura Rozszerzona Informatyka Maj 2024

2 pkt
Zadanie 1.1.

Podpunkt 1.1. (0–2 pkt)

Podaj wynik działania algorytmu dla plansz podanych na rysunkach poniżej, gdzie nn to liczba wierszy, a mm to liczba kolumn danej planszy.

a) n=3,m=3n = 3, m = 3
Wynik: ________________________
b) n=5,m=3n = 5, m = 3
Wynik: ________________________
c) n=5,m=5n = 5, m = 5
Wynik: ________________________
💡 Pokaż rozwiązanie krok po kroku
  • 1

    Krok 1: Analiza planszy A

    Zgodnie z naszymi ustaleniami algorytm szuka ciągłej ścieżki z lewego górnego do prawego dolnego rogu, poruszając się wyłącznie w dół lub w prawo po białych polach.

    • Z pola (1,1)(1, 1) możemy iść w prawo do (1,2)(1, 2).
    • Z pola (1,2)(1, 2) możemy iść w dół do (2,2)(2, 2) (które jest białe).
    • Z pola (2,2)(2, 2) możemy iść w dół do (3,2)(3, 2).
    • Z pola (3,2)(3, 2) idziemy w prawo do celu (3,3)(3, 3).

    Wynik a): PRAWDA

  • 2

    Krok 2: Analiza planszy B

    Spróbujmy wyznaczyć trasę dla planszy B:

    • Początek to (1,1)(1, 1). W drugim wierszu białe jest tylko pole (2,3)(2, 3). Zatem musimy przejść przez pierwszy wiersz aż do prawej krawędzi: (1,1)(1,2)(1,3)(1, 1) \rightarrow (1, 2) \rightarrow (1, 3).
    • Następnie z (1,3)(1, 3) idziemy w dół: (2,3)(3,3)(2, 3) \rightarrow (3, 3).
    • Jesteśmy w komórce (3,3)(3, 3). Algorytm pozwala poruszać się tylko w prawo lub w dół. Nie możemy cofnąć się w lewo.
    • Z komórki (3,3)(3, 3) ruch w dół jest zablokowany, ponieważ pole (4,3)(4, 3) jest czarne.
    • Aby dojść do celu (5,3)(5, 3), musielibyśmy ominąć ten czarny blok, przechodząc przez białe pole (4,1)(4, 1). Jednakże dostęp do (4,1)(4, 1) z góry blokuje czarne pole (2,1)(2, 1). Mamy absolutną blokadę z każdej ze stron.

    Wynik b): FAŁSZ

  • 3

    Krok 3: Analiza planszy C

    Szukamy ścieżki omijającej czarne "przeszkody":

    1. Zaczynamy na (1,1)(1, 1) i schodzimy na (2,1)(2, 1).
    2. Idziemy w prawo na (2,2)(2, 2) (ponieważ (3,1)(3, 1) jest czarne).
    3. Z (2,2)(2, 2) możemy iść bezpiecznie w dół, przez cały biały "korytarz": (3,2)(4,2)(3, 2) \rightarrow (4, 2).
    4. Z (4,2)(4, 2) idziemy w prawo: (4,3)(4,4)(4, 3) \rightarrow (4, 4).
    5. Z (4,4)(4, 4) schodzimy w dół na (5,4)(5, 4).
    6. Na koniec jeden krok w prawo do celu: (5,5)(5, 5).

    Mimo skomplikowanego układu przeszkód, udało nam się wyznaczyć ciągłą, poprawną trasę krok po kroku.

    Wynik c): PRAWDA

Matura Rozszerzona Informatyka Maj 2024

2 pkt
Zadanie 1.2.

Podpunkt 1.2. (0–2 pkt)

Przy założeniu, że lewy górny i prawy dolny róg planszy są białe, podaj przykład planszy (zamaluj odpowiednie pola lub wpisz w nie zera):

a) o 5 wierszach i 5 kolumnach, na której co najwyżej 2 pola są czarne, a wynikiem działania algorytmu jest FAŁSZ

b) o 4 wierszach i 4 kolumnach, na której co najmniej 9 pól jest czarnych, a wynikiem działania algorytmu jest PRAWDA.

💡 Pokaż rozwiązanie krok po kroku
  • 1

    Krok 1: Rozwiązanie podpunktu a)

    Aby wynik algorytmu wynosił FAŁSZ, musimy całkowicie zablokować możliwość przejścia z lewego górnego do prawego dolnego rogu.

    Mamy do dyspozycji tylko 2 czarne pola. Najbardziej efektywnym sposobem odcięcia ścieżki jest zablokowanie samego wyjścia z punktu startowego (1,1)(1,1) lub wejścia do punktu końcowego (5,5)(5,5). Z punktu (1,1)(1,1) możemy iść tylko w prawo na (1,2)(1,2) i w dół na (2,1)(2,1). Jeśli oba te pola będą czarne, dron/pionek zostanie całkowicie uwięziony na starcie.

    start
    cel
  • 2

    Krok 2: Rozwiązanie podpunktu b)

    Aby wynik wynosił PRAWDA, musi istnieć chociaż jedna poprawna ścieżka. Chcemy przy tym użyć co najmniej 9 czarnych pól na planszy 4×44 \times 4 (czyli 1616 pól w sumie).

    Minimalna liczba kroków (i liczba zajętych białych pól) potrzebna do przejścia planszy 4×44 \times 4 wynosi dokładnie 7. Ponieważ 167=916 - 7 = 9, oznacza to, że musimy wytyczyć jedną, najprostszą możliwą ścieżkę, a całą resztę (dokładnie 9 pól) zamalować na czarno!

    Przykładowa prosta ścieżka: idziemy do samego końca w prawo (górna krawędź), a potem do samego dołu (prawa krawędź). Zobaczmy, jak to wygląda:

Matura Rozszerzona Informatyka Maj 2024

1 pkt
Zadanie 1.3.

Podpunkt 1.3. (0–1 pkt)

Dana jest kwadratowa plansza o nn wierszach i nn kolumnach.

Podaj, jaka jest największa możliwa liczba czarnych pól na tej planszy, dla których wynikiem działania algorytmu jest PRAWDA.

Odpowiedź: ________________________
💡 Pokaż rozwiązanie krok po kroku
  • 1

    Krok 1: Analiza najkrótszej ścieżki

    Aby wynik działania algorytmu wynosił PRAWDA, na planszy musi istnieć przynajmniej jedna ciągła ścieżka złożona wyłącznie z białych pól, prowadząca z lewego górnego rogu (1,1)(1, 1) do prawego dolnego rogu (n,n)(n, n). Zgodnie z analizą kodu, możemy poruszać się tylko w prawo i w dół.

    Najkrótsza możliwa ścieżka na kwadratowej siatce o wymiarach n×nn \times n wymaga wykonania dokładnie n1n - 1 kroków w dół oraz n1n - 1 kroków w prawo.

    Łączna liczba pól, które tworzą taką minimalną ścieżkę, to liczba wszystkich kroków plus pole startowe: (n1)+(n1)+1=2n1(n - 1) + (n - 1) + 1 = 2n - 1. Wszystkie te pola muszą być białe, aby algorytm zwrócił prawdę.

  • 2

    Krok 2: Maksymalizacja czarnych pól

    Aby liczba czarnych pól była jak największa, liczba białych pól musi być jak najmniejsza. Najmniejsza dopuszczalna liczba białych pól to właśnie nasza pojedyncza ścieżka składająca się z 2n12n - 1 pól. Wszystkie pozostałe pola na planszy możemy bez obaw zamalować na czarno.

    Całkowita liczba pól na planszy wynosi n2n^2.

    Maksymalna liczba czarnych pól to różnica między wszystkimi polami a polami białymi (ścieżką):

    n2(2n1)=n22n+1n^2 - (2n - 1) = n^2 - 2n + 1

    Zauważ, że otrzymany wzór to wzór skróconego mnożenia, który można zapisać jako (n1)2(n - 1)^2.

    Odpowiedź: n22n+1n^2 - 2n + 1 (lub w postaci zwiniętej: (n1)2(n - 1)^2)

Matura Rozszerzona Informatyka Maj 2024

2 pkt
Zadanie 2.1.

Zadanie 2. Cyfry

Przeanalizuj poniższy algorytm, który dla danej nieujemnej liczby całkowitej nn oblicza liczbę całkowitą cc.

b <- 1
c <- 0
dopóki n > 0 wykonuj
  a <- n mod 10
  n <- n div 10
  jeżeli (a mod 2 = 0)
      c <- c + b * (a div 2)
  w przeciwnym razie
      c <- c + b
  b <- b * 10

Uwaga: x mod y, x div y oznaczają – odpowiednio – resztę i iloraz z dzielenia całkowitego xx przez yy.

Zadanie 2.1. (0–2 pkt)

Uzupełnij poniższą tabelę – dla każdej z podanych liczb wpisz wartość zmiennej cc po wykonaniu algorytmu oraz liczbę wykonań instrukcji c <- c + b.

nnWartość cc po wykonaniu algorytmu dla danego nnLiczba wykonań instrukcji
c <- c + b
33658113143
5421021211012
87654321012345678413121110111213148
💡 Pokaż rozwiązanie krok po kroku
  • 1

    Krok 1: Analiza działania algorytmu

    Aby sprawnie uzupełnić tabelę, musimy zrozumieć, co algorytm robi z cyframi liczby nn. Przetwarza on liczbę od prawej do lewej (od jedności w górę) – wyłuskuje ostatnią cyfrę (a <- n mod 10) i odcina ją od liczby (n <- n div 10).

    • Zmienna b kontroluje aktualną pozycję dziesiętną budowanej liczby cc (kolejno 1, 10, 100, 1000 itd.).
    • Jeżeli cyfra jest parzysta (a mod 2 = 0): algorytm wstawia w to miejsce połowę tej cyfry (a div 2).
    • Jeżeli cyfra jest nieparzysta: wykonywana jest instrukcja c <- c + b. Dodanie samego b oznacza wstawienie w to miejsce cyfry 1 (bo 1b=b1 \cdot b = b).

    Wniosek: Algorytm podmienia każdą cyfrę parzystą na jej połowę, a każdą nieparzystą na 1. Liczba wykonań instrukcji c <- c + b to po prostu liczba cyfr nieparzystych w oryginalnej liczbie nn.

  • 2

    Krok 2: Uzupełnienie dla n = 542102

    Rozpisujemy liczbę cyfra po cyfrze od lewej do prawej, stosując nasze zasady:

    • 5 (nieparzysta) \rightarrow zamienia się na 1
    • 4 (parzysta) \rightarrow zamienia się na 4/2=4 / 2 = 2
    • 2 (parzysta) \rightarrow zamienia się na 2/2=2 / 2 = 1
    • 1 (nieparzysta) \rightarrow zamienia się na 1
    • 0 (parzysta) \rightarrow zamienia się na 0/2=0 / 2 = 0
    • 2 (parzysta) \rightarrow zamienia się na 2/2=2 / 2 = 1

    Sklejając wynik otrzymujemy c=121101c = 121101.

    Szukamy liczby cyfr nieparzystych, by zliczyć wywołania instrukcji. W liczbie 542102 nieparzyste są tylko cyfry 5 oraz 1. Liczba wywołań wynosi zatem 2.

  • 3

    Krok 3: Uzupełnienie dla n = 87654321012345678

    Analogicznie, mapujemy bardzo długą liczbę znak po znaku (parzyste dzielimy na pół, nieparzyste stają się jedynkami):

    • 8 $\rightarrow$ 4, 7 $\rightarrow$ 1, 6 $\rightarrow$ 3, 5 $\rightarrow$ 1, 4 $\rightarrow$ 2, 3 $\rightarrow$ 1, 2 $\rightarrow$ 1, 1 $\rightarrow$ 1, 0 $\rightarrow$ 0
    • 1 $\rightarrow$ 1, 2 $\rightarrow$ 1, 3 $\rightarrow$ 1, 4 $\rightarrow$ 2, 5 $\rightarrow$ 1, 6 $\rightarrow$ 3, 7 $\rightarrow$ 1, 8 $\rightarrow$ 4

    Po sklejeniu otrzymujemy ogromną liczbę: c=41312111011121314c = 41312111011121314.

    Na koniec liczymy ilość cyfr nieparzystych w wyjściowym nn:


    Są to kolejno: 7, 5, 3, 1, 1, 3, 5, 7.


    Jest ich w sumie 8, więc instrukcja w gałęzi w przeciwnym razie wykona się dokładnie 8 razy.

Matura Rozszerzona Informatyka Maj 2024

1 pkt
Zadanie 2.2.

Podpunkt 2.2. (0–1 pkt)

Podaj wartość cc po wykonaniu algorytmu dla osiemnastocyfrowej liczby całkowitej nn, w której pierwszych sześć cyfr to 3, następnych sześć cyfr to 6, a pozostałych sześć cyfr to 9.

c=c = ........................................................................................

💡 Pokaż rozwiązanie krok po kroku
  • 1

    Krok 1: Budowa liczby wejściowej

    Zgodnie z poleceniem, liczba nn składa się z 18 cyfr. Podzielona jest na trzy równe sekcje po 6 cyfr:

    • Pierwsze 6 cyfr to 3, czyli blok: 333333
    • Kolejne 6 cyfr to 6, czyli blok: 666666
    • Ostatnie 6 cyfr to 9, czyli blok: 999999

    Sklejając te sekcje, cała wejściowa liczba nn to: 333333666666999999.

  • 2

    Krok 2: Zastosowanie reguł algorytmu

    Z poprzedniej analizy algorytmu wiemy, że przekształca on każdą cyfrę niezależnie, z zachowaniem jej pozycji (rzędu wielkości). Przypomnijmy zasady:

    • Każda cyfra nieparzysta zamieniana jest na 1.
    • Każda cyfra parzysta zamieniana jest na połowę swojej wartości.

    Przekształcamy poszczególne bloki liczby nn:

    • Blok 333333 (cyfry nieparzyste) zamienia się na same jedynki: 111111.
    • Blok 666666 (cyfry parzyste) dzielimy na pół i zamienia się on na: 333333.
    • Blok 999999 (cyfry nieparzyste) znów zamienia się na same jedynki: 111111.
  • 3

    Krok 3: Wynik końcowy

    Na koniec wystarczy połączyć wszystkie trzy przetworzone bloki w jedną spójną liczbę, zachowując ich pierwotną kolejność (od lewej do prawej).

    c = 111111333333111111

Matura Rozszerzona Informatyka Maj 2024

3 pkt
Zadanie 3.1.

Zadanie 3. Nieparzysty skrót

Nieparzystym skrótem dodatniej liczby całkowitej nn nazwiemy dodatnią liczbę całkowitą mm, która powstaje przez usunięcie cyfr parzystych z zapisu dziesiętnego liczby nn. Nieparzysty skrót liczby całkowitej nn nie istnieje, gdy jej zapis dziesiętny składa się tylko z cyfr parzystych.

Przykład:
  • Nieparzystym skrótem liczby 294762 jest liczba 97.
  • Nieparzystym skrótem liczby 39101 jest liczba 3911.
  • Nieparzysty skrót liczby 224 nie istnieje.

Zadanie 3.1. (0–3 pkt)

W postaci pseudokodu lub w wybranym języku programowania napisz funkcję, która dla dodatniej liczby całkowitej nn, takiej że istnieje dla niej nieparzysty skrót, wyznaczy liczbę mmnieparzysty skrót liczby nn.

Uwaga: Twój algorytm może używać wyłącznie zmiennych przechowujących liczby całkowite oraz może operować wyłącznie na liczbach całkowitych. W zapisie możesz wykorzystać tylko operacje arytmetyczne: dodawanie, odejmowanie, mnożenie, dzielenie, dzielenie całkowite, resztę z dzielenia oraz porównywanie liczb, instrukcje sterujące, przypisania do zmiennych lub samodzielnie napisane funkcje, wykorzystujące wyżej wymienione operacje. Zabronione jest używanie funkcji wbudowanych oraz operatorów innych niż wymienione.

Specyfikacja:
Dane:
  • nn – dodatnia liczba całkowita, taka że istnieje dla niej nieparzysty skrót
Wynik:
  • mmnieparzysty skrót liczby nn
💡 Pokaż rozwiązanie krok po kroku
  • 1

    Krok 1: Konstrukcja algorytmu liczbowego

    Z uwagi na rygorystyczne obostrzenia, nie możemy zamienić liczby na stringa (tekst) i po prostu "wyciąć" parzystych znaków. Musimy przetwarzać liczbę matematycznie, operując na systemie dziesiętnym.

    • Odczytywanie cyfr: Reszta z dzielenia przez 10 (n mod 10) zawsze daje nam ostatnią cyfrę liczby. Dzielenie całkowite przez 10 (n div 10) usuwa tę ostatnią cyfrę. Pozwala to na przetwarzanie liczby od prawej do lewej (od jedności).
    • Warunek: Sprawdzamy, czy wyłuskana cyfra jest nieparzysta, badając czy reszta z jej dzielenia przez 2 nie jest równa zero (cyfra mod 2 != 0).
    • Sklejanie nowej liczby: Skoro czytamy cyfry od prawej do lewej, budując nową liczbę mm musimy umieszczać wybrane cyfry na odpowiednich pozycjach (jedności, dziesiątki, setki). Użyjemy do tego zmiennej mnoznik. Gdy znajdziemy nieparzystą cyfrę, dodajemy do mm wartość cyfra * mnoznik, a następnie mnożymy mnoznik przez 10, by przygotować odpowiednią pozycję dla kolejnej trafionej cyfry.
  • 2

    Krok 2: Opcja A – Pseudokod

    Poniżej znajduje się poprawne rozwiązanie zapisane w uniwersalnym pseudokodzie.

    funkcja nieparzysty_skrot(n):
      m <- 0
      mnoznik <- 1
      
      dopóki n > 0 wykonuj
          cyfra <- n mod 10
          n <- n div 10
          
          jeżeli cyfra mod 2 <> 0
              m <- m + cyfra * mnoznik
              mnoznik <- mnoznik * 10
              
      zwróć m
  • 3

    Krok 3: Opcja B – Język Python

    To samo rozwiązanie w języku Python. Zwróć uwagę na zastosowanie operatora //, który gwarantuje dzielenie całkowite (bez części ułamkowej).

    def nieparzysty_skrot(n):
      m = 0
      mnoznik = 1
      
      while n > 0:
          cyfra = n % 10
          n = n // 10
          
          if cyfra % 2 != 0:
              m = m + cyfra * mnoznik
              mnoznik = mnoznik * 10
              
      return m
  • 4

    Krok 4: Opcja C – Język C++

    Wersja w C++. Warto tutaj użyć odpowiednich typów dla bardzo dużych liczb (np. long long, choć standardowy int w zupełności wystarczy dla logiki opisanej w specyfikacji maturalnej). Zwykłe dzielenie / na liczbach całkowitych automatycznie obcina resztę.

    int nieparzysty_skrot(int n) {
      int m = 0;
      int mnoznik = 1;
      
      while (n > 0) {
          int cyfra = n % 10;
          n = n / 10;
          
          if (cyfra % 2 != 0) {
              m = m + cyfra * mnoznik;
              mnoznik = mnoznik * 10;
          }
      }
      
      return m;
    }

Matura Rozszerzona Informatyka Maj 2024

3 pkt
Zadanie 3.2.

Podpunkt 3.2. (0–3 pkt)

Plik skrot.txt zawiera 200 dodatnich liczb całkowitych, mniejszych od 30 000. Każda liczba jest zapisana w osobnym wierszu. Dla co najmniej jednej z tych liczb nie istnieje nieparzysty skrót.

Napisz program, który wyznaczy liczbę wszystkich liczb z pliku skrot.txt, dla których nie istnieje nieparzysty skrót, oraz poda największą z nich. Odpowiedź zapisz w pliku wyniki3_2.txt.

Plik skrot_przyklad.txt zawiera 20 liczb mniejszych od 30 000. Dla danych zawartych w pliku skrot_przyklad.txt prawidłową odpowiedzią jest:

2
2428

(w pliku są dwie liczby, dla których nie istnieje nieparzysty skrót: 266 i 2428; 2428 jest największą z nich).

💡 Pokaż rozwiązanie krok po kroku
  • 1

    Krok 1: Logika sprawdzania istnienia skrótu

    Z definicji w zadaniu 3.0 wiemy, że nieparzysty skrót nie istnieje wtedy i tylko wtedy, gdy wszystkie cyfry w liczbie są parzyste. Innymi słowy, jeśli w liczbie znajdziemy choć jedną cyfrę nieparzystą, to skrót istnieje.

    Aby to sprawdzić, napiszemy prostą funkcję pomocniczą (np. czy_ma_skrot). Będziemy odcinać kolejne cyfry liczby od prawej strony (używając modulo 10 i dzielenia całkowitego przez 10). Jeśli natrafimy na cyfrę nieparzystą (cyfra mod 2 != 0), od razu zwracamy prawdę. Jeśli pętla się zakończy i nie znajdziemy żadnej cyfry nieparzystej, zwracamy fałsz.

  • 2

    Krok 2: Algorytm główny

    W głównej części programu musimy przetworzyć plik tekstowy. Będziemy potrzebować dwóch zmiennych:

    • licznik – do zliczania liczb bez skrótu (początkowo 0).
    • najwieksza – do zapamiętania największej takiej liczby (początkowo np. -1).

    Dla każdej wczytanej liczby wywołujemy naszą funkcję sprawdzającą. Jeśli zwróci ona fałsz (czyli skrót NIE istnieje), zwiększamy licznik i ewentualnie aktualizujemy zmienną najwieksza, jeśli obecna liczba jest od niej większa.

  • 3

    Krok 3: Rozwiązanie – język Python

    def czy_ma_skrot(n):
      # Przechodzimy po wszystkich cyfrach liczby
      while n > 0:
          cyfra = n % 10
          if cyfra % 2 != 0:
              return True # Znaleziono cyfrę nieparzystą - skrót istnieje
          n = n // 10
      return False # Same cyfry parzyste - skrót nie istnieje
    
    def solve_3_2():
      licznik = 0
      najwieksza = -1
      
      with open('skrot.txt', 'r') as file:
          for line in file:
              liczba = int(line.strip())
              
              # Interesują nas liczby, dla których skrót NIE istnieje
              if not czy_ma_skrot(liczba):
                  licznik += 1
                  if liczba > najwieksza:
                      najwieksza = liczba
                      
      print(f"Ilość liczb bez skrótu: {licznik}")
      print(f"Największa z nich: {najwieksza}")
    
      # Zapis do pliku
      with open('wyniki3_2.txt', 'w') as out_file:
          out_file.write(f"{licznik}\n{najwieksza}\n")
    
    solve_3_2()
  • 4

    Krok 4: Rozwiązanie – język C++

    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    // Funkcja zwracająca true, jeśli liczba posiada nieparzysty skrót
    bool czy_ma_skrot(int n) {
      while (n > 0) {
          int cyfra = n % 10;
          if (cyfra % 2 != 0) {
              return true; // Znaleziono cyfrę nieparzystą
          }
          n /= 10;
      }
      return false; // Brak cyfr nieparzystych
    }
    
    int main() {
      ifstream file("skrot.txt");
      ofstream out_file("wyniki3_2.txt");
      
      int liczba;
      int licznik = 0;
      int najwieksza = -1;
      
      // Odczyt dopóki plik nie jest pusty
      while (file >> liczba) {
          if (!czy_ma_skrot(liczba)) {
              licznik++;
              if (liczba > najwieksza) {
                  najwieksza = liczba;
              }
          }
      }
      
      cout << "Ilosc liczb bez skrotu: " << licznik << endl;
      cout << "Najwieksza z nich: " << najwieksza << endl;
      
      // Zapisz wyniki do pliku
      out_file << licznik << "\n" << najwieksza << "\n";
      
      file.close();
      out_file.close();
      
      return 0;
    }

Matura Rozszerzona Informatyka Maj 2024

4 pkt
Zadanie 3.3.

Podpunkt 3.3. (0–4 pkt)

Plik skrot2.txt zawiera 200 dodatnich liczb całkowitych, mniejszych od 30 000. Każda liczba jest zapisana w osobnym wierszu. Dla każdej z tych liczb istnieje nieparzysty skrót.

Napisz program, który wypisze te liczby z pliku skrot2.txt, dla których największy wspólny dzielnik liczby i jej nieparzystego skrótu jest równy 7. Odpowiedź zapisz w pliku wyniki3_3.txt. Twój program powinien wypisać w każdym wierszu wyniku po jednej liczbie z pliku skrot2.txt, dla której jest spełniony powyższy warunek.

Plik skrot2_przyklad.txt zawiera 20 liczb spełniających warunki zadania. Dla danych zawartych w pliku skrot2_przyklad.txt prawidłową odpowiedzią jest:

4872
23527

💡 Pokaż rozwiązanie krok po kroku
  • 1

    Krok 1: Logika algorytmu

    To zadanie wymaga od nas połączenia dwóch koncepcji:

    • Obliczenie nieparzystego skrótu: Wykorzystamy funkcję, którą przygotowaliśmy w podpunkcie 3.1. Przekształca ona matematycznie liczbę, usuwając z niej cyfry parzyste.
    • Obliczenie Największego Wspólnego Dzielnika (NWD): Użyjemy do tego klasycznego algorytmu Euklidesa, który pozwala na szybkie znalezienie NWD dwóch liczb całkowitych.

    Dla każdej wczytanej z pliku liczby nn, wywołujemy funkcję tworzącą jej skrót mm. Następnie sprawdzamy, czy NWD(n,m)==7\text{NWD}(n, m) == 7. Jeśli warunek jest spełniony, wypisujemy liczbę na ekran i zapisujemy ją do pliku wynikowego.

  • 2

    Krok 2: Rozwiązanie – język Python

    W Pythonie moglibyśmy użyć wbudowanej funkcji math.gcd, jednak dla celów edukacyjnych (i całkowitej pewności maturalnej) napisałem klasyczną funkcję nwd.

    def nieparzysty_skrot(n):
      m = 0
      mnoznik = 1
      while n > 0:
          cyfra = n % 10
          n = n // 10
          if cyfra % 2 != 0:
              m = m + cyfra * mnoznik
              mnoznik = mnoznik * 10
      return m
    
    def nwd(a, b):
      # Klasyczny algorytm Euklidesa
      while b > 0:
          a, b = b, a % b
      return a
    
    def solve_3_3():
      with open('skrot2.txt', 'r') as in_file, open('wyniki3_3.txt', 'w') as out_file:
          for line in in_file:
              liczba = int(line.strip())
              skrot = nieparzysty_skrot(liczba)
              
              # Sprawdzamy warunek zadania
              if nwd(liczba, skrot) == 7:
                  print(liczba)
                  out_file.write(f"{liczba}\n")
    
    solve_3_3()
  • 3

    Krok 3: Rozwiązanie – język C++

    Oto kompletny kod w języku C++. Zastosowano analogiczną logikę, opartą na dwóch niezależnych funkcjach pomocniczych obsługujących wyznaczanie skrótu oraz dzielnika.

    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    // Funkcja wyznaczająca nieparzysty skrót
    int nieparzysty_skrot(int n) {
      int m = 0;
      int mnoznik = 1;
      while (n > 0) {
          int cyfra = n % 10;
          if (cyfra % 2 != 0) {
              m = m + cyfra * mnoznik;
              mnoznik *= 10;
          }
          n /= 10;
      }
      return m;
    }
    
    // Algorytm Euklidesa dla NWD
    int nwd(int a, int b) {
      while (b > 0) {
          int temp = b;
          b = a % b;
          a = temp;
      }
      return a;
    }
    
    int main() {
      ifstream in_file("skrot2.txt");
      ofstream out_file("wyniki3_3.txt");
      
      int liczba;
      
      // Odczyt pliku do końca
      while (in_file >> liczba) {
          int skrot = nieparzysty_skrot(liczba);
          
          // Warunek zadania
          if (nwd(liczba, skrot) == 7) {
              cout << liczba << endl;
              out_file << liczba << "\n";
          }
      }
      
      in_file.close();
      out_file.close();
      
      return 0;
    }

Matura Rozszerzona Informatyka Maj 2024

2 pkt
Zadanie 4.1.

Zadanie 4. Liczby

Plik liczby.txt składa się z dwóch wierszy:

  • pierwszy wiersz pliku zawiera 3000 liczb pierwszych z przedziału [2, 2000]
  • drugi wiersz pliku zawiera 20 liczb całkowitych z przedziału [2, 1 000 000 000].

Liczby w wierszach są rozdzielone znakami spacji.

Napisz program (lub kilka programów), który(-e) znajdzie(-ą) odpowiedzi do podanych zadań. Każdą odpowiedź zapisz w pliku wyniki4.txt i poprzedź ją numerem oznaczającym zadanie.

Do Twojej dyspozycji jest plik liczby_przyklad.txt, który zawiera 200 liczb w pierwszym wierszu (są to wyłącznie liczby 2, 3, 5, 7 i 31) oraz 20 liczb w drugim wierszu. Odpowiedzi dla danych z tego pliku są umieszczone pod każdym zadaniem. Pamiętaj, że Twój program musi ostatecznie zadziałać na pliku liczby.txt z 3000 liczb w pierwszym wierszu.

Zadanie 4.1. (0–2 pkt)

Podaj, ile liczb z pierwszego wiersza jest dzielnikiem jakiejkolwiek liczby spośród liczb z drugiego wiersza.

Dla pliku liczby_przyklad.txt odpowiedzią jest 199
(tylko liczba 31, która występuje raz, nie jest dzielnikiem żadnej z liczb w drugim wierszu).

💡 Pokaż rozwiązanie krok po kroku
  • 1

    Krok 1: Analiza logiczna dla podpunktu 4.1

    W tym zadaniu musimy sprawdzić każdą liczbę z pierwszego wiersza z osobna. Zwróć uwagę na kluczowy zwrot: "ile liczb z pierwszego wiersza". Przykład wyraźnie mówi, że jeśli jakaś liczba powtarza się w pierwszym wierszu (np. dwójka) i jest dzielnikiem, to liczymy każde jej wystąpienie.

    Dla każdej liczby pp z pierwszego wiersza przeglądamy liczby z drugiego wiersza. Jeśli znajdziemy chociaż jedną taką liczbę nn, dla której n%p==0n \% p == 0 (czyli reszta z dzielenia wynosi zero), to zaliczamy liczbę pp do wyniku i przerywamy sprawdzanie drugiego wiersza (aby nie policzyć jej podwójnie).

Matura Rozszerzona Informatyka Maj 2024

2 pkt
Zadanie 4.2.

Zadanie 4.2. (0–2 pkt)

Spośród liczb z pierwszego wiersza podaj liczbę, która jest sto pierwszą liczbą w kolejności, licząc od największej po ich uporządkowaniu.

Przykład: wśród liczb 2, 4, 2, 3, 3, 4 drugą w kolejności, licząc od największej, jest liczba 4.

Dla pliku liczby_przyklad.txt odpowiedzią jest 5.

💡 Pokaż rozwiązanie krok po kroku
  • 1

    Krok 1: Analiza logiczna dla podpunktu 4.2

    Kluczowa jest tutaj wskazówka z przykładu. Jeśli uporządkujemy podany w przykładzie ciąg malejąco, otrzymamy: 4, 4, 3, 3, 2, 2. "Druga w kolejności" to liczba znajdująca się na drugiej pozycji, czyli 4.

    To oznacza, że nie usuwamy duplikatów! Wystarczy wczytać pierwszy wiersz do zwykłej tablicy/listy, posortować ją malejąco, a następnie odczytać element na 101. pozycji (pamiętając, że w programowaniu indeksy zaczynają się od zera, więc interesuje nas element pod indeksem 100).

  • 2

    Krok 2: Zintegrowane rozwiązanie w Pythonie

    Python jest stworzony do takich zadań. Użyjemy split() do automatycznego rozdzielenia liczb po spacjach i od razu zrobimy z nich listy liczb całkowitych za pomocą map.

    def solve_4():
      # Odczyt danych
      with open('liczby.txt', 'r') as f:
          linie = f.readlines()
          
      # Zamiana tekstowych linii na listy liczb całkowitych
      wiersz1 = list(map(int, linie[0].split()))
      wiersz2 = list(map(int, linie[1].split()))
      
      # --- ZADANIE 4.1 ---
      wynik_4_1 = 0
      for p in wiersz1:
          for n in wiersz2:
              if n % p == 0:
                  wynik_4_1 += 1
                  break # Jeśli znaleźliśmy jakikolwiek dzielnik, przerywamy by nie dublować
                  
      print(f"4.1. Wynik: {wynik_4_1}")
      
      # --- ZADANIE 4.2 ---
      # Sortujemy malejąco
      wiersz1_posortowany = sorted(wiersz1, reverse=True)
      
      # Sto pierwsza liczba to indeks 100 (bo liczymy od 0)
      wynik_4_2 = wiersz1_posortowany[100]
      
      print(f"4.2. Wynik: {wynik_4_2}")
    
    solve_4()
  • 3

    Krok 3: Zintegrowane rozwiązanie w C++

    W języku C++ najwygodniej posłużyć się strumieniami napisowymi (stringstream), aby sprawnie wyciągnąć liczby z poszczególnych linii.

    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <sstream>
    #include <algorithm>
    
    using namespace std;
    
    int main() {
      ifstream file("liczby.txt");
      string linia1, linia2;
      
      // Wczytujemy całe linie jako tekst
      getline(file, linia1);
      getline(file, linia2);
      
      vector<int> wiersz1, wiersz2;
      stringstream ss1(linia1), ss2(linia2);
      int liczba;
      
      // Konwertujemy i pakujemy do wektorów
      while(ss1 >> liczba) wiersz1.push_back(liczba);
      while(ss2 >> liczba) wiersz2.push_back(liczba);
      
      // --- ZADANIE 4.1 ---
      int wynik_4_1 = 0;
      for(int p : wiersz1) {
          for(int n : wiersz2) {
              if(n % p == 0) {
                  wynik_4_1++;
                  break;
              }
          }
      }
      cout << "4.1. Wynik: " << wynik_4_1 << endl;
      
      // --- ZADANIE 4.2 ---
      // Skopiowanie i sortowanie malejące
      vector<int> wiersz1_posortowany = wiersz1;
      sort(wiersz1_posortowany.rbegin(), wiersz1_posortowany.rend());
      
      cout << "4.2. Wynik: " << wiersz1_posortowany[100] << endl;
      
      return 0;
    }

Matura Rozszerzona Informatyka Maj 2024

3 pkt
Zadanie 4.3.

Zadanie 4.3. (0–3 pkt)

Dla każdej z liczb z drugiego wiersza rozstrzygnij, czy da się ją przedstawić jako iloczyn jedynie liczb z pierwszego wiersza. Przy tym liczba wystąpień danego czynnika w iloczynie nie może być większa niż liczba wystąpień tego czynnika w pierwszym wierszu. Znajdź wszystkie liczby, które da się tak przedstawić, i je wypisz.

Dla pliku liczby_przyklad.txt odpowiedzią są liczby:
10 12 14 15 18 20 21 25 27 28
(liczbę 16 można przedstawić jako iloczyn 2·2·2·2, jednak w pierwszym wierszu liczba 2 występuje tylko dwa razy, więc 16 nie należy do rozwiązania. Podobnie jest z liczbą 24, którą można przedstawić jako iloczyn 2·2·2·3).

💡 Pokaż rozwiązanie krok po kroku
  • 1

    Krok 1: Strategia algorytmiczna (rozkład na czynniki pierwsze)

    Z pierwszego wiersza musimy stworzyć "magazyn" dostępnych czynników. Użyjemy struktury słownikowej (mapy), która zliczy wystąpienia każdej liczby pierwszej z wiersza 1.

    Następnie dla każdej liczby z drugiego wiersza przeprowadzimy rozkład na czynniki pierwsze. Zliczymy, ile razy dany czynnik pojawia się w rozkładzie tej liczby. Jeżeli dla jakiegokolwiek czynnika nasza liczba potrzebuje go więcej, niż mamy w "magazynie" (lub wymaga czynnika, którego w ogóle tam nie ma), odrzucamy ją.

  • 2

    Krok 2: Kod w języku Python

    from collections import Counter
    
    def solve_4_3():
      with open('liczby.txt', 'r') as f:
          linie = f.readlines()
          
      wiersz1 = list(map(int, linie[0].split()))
      wiersz2 = list(map(int, linie[1].split()))
      
      # "Magazyn" dostępnych czynników
      dostepne = Counter(wiersz1)
      wyniki = []
      
      for n in wiersz2:
          temp = n
          czynniki_n = {}
          d = 2
          
          # Rozkład na czynniki pierwsze
          while d * d <= temp:
              while temp % d == 0:
                  czynniki_n[d] = czynniki_n.get(d, 0) + 1
                  temp //= d
              d += 1
          if temp > 1:
              czynniki_n[temp] = czynniki_n.get(temp, 0) + 1
              
          # Sprawdzenie z magazynem
          czy_mozna = True
          for czynnik, ilosc in czynniki_n.items():
              if dostepne.get(czynnik, 0) < ilosc:
                  czy_mozna = False
                  break
                  
          if czy_mozna:
              wyniki.append(n)
              
      print("4.3. Odpowiedź:")
      print(" ".join(map(str, wyniki)))
    
    solve_4_3()

Matura Rozszerzona Informatyka Maj 2024

3 pkt
Zadanie 4.4.

Zadanie 4.4. (0–3 pkt)

Znajdź w ciągu liczb z pierwszego wiersza spójny fragment, który zawiera co najmniej 50 elementów i którego średnia arytmetyczna jest największa.
Jeżeli jest więcej niż jeden taki fragment, wybierz ten, który występuje jako pierwszy w pliku liczby.txt.

W odpowiedzi wypisz:
  • znalezioną najwyższą średnią
  • liczbę elementów ciągu z tą najwyższą średnią
  • liczbę, która jest pierwszym elementem tego ciągu.

Dla pliku liczby_przyklad.txt odpowiedzią jest:
5,52 50 5
(największa średnia to 5,52 dla 50 liczb zaczynających się od liczby 5).

💡 Pokaż rozwiązanie krok po kroku
  • 1

    Krok 1: Strategia algorytmiczna (szukanie podciągu)

    Tablica w pierwszym wierszu ma 3000 elementów. Maksymalna liczba ciągów do sprawdzenia to około 30002/24.53000^2 / 2 \approx 4.5 miliona. Taka złożoność (O(n2)O(n^2)) wykona się w ułamku sekundy, więc brutalna siła (ang. brute-force) optymalizowana sumą kroczącą jest idealna.

    Będziemy iterować po każdym możliwym początku ciągu (i). Dla danego początku, będziemy dodawać kolejne elementy do sumy (j). Kiedy długość przekroczy lub zrówna się z 50 elementami, wyliczymy średnią arytmetyczną. Ponieważ w przypadku remisów interesuje nas "najwcześniejszy" fragment, zaktualizujemy maksimum tylko wtedy, gdy nowa średnia będzie ostro większa (>) od dotychczasowej.

  • 2

    Krok 2: Kod w języku Python

    def solve_4_4():
      with open('liczby.txt', 'r') as f:
          linie = f.readlines()
      wiersz1 = list(map(int, linie[0].split()))
      
      max_srednia = -1.0
      najlepsza_dlugosc = 0
      najlepszy_start_wartosc = 0
      
      n = len(wiersz1)
      
      for i in range(n):
          obecna_suma = 0
          for j in range(i, n):
              obecna_suma += wiersz1[j]
              dlugosc = j - i + 1
              
              if dlugosc >= 50:
                  srednia = obecna_suma / dlugosc
                  
                  # Znak > gwarantuje, że przy remisie zostanie 
                  # ten znaleziony jako pierwszy
                  if srednia > max_srednia:
                      max_srednia = srednia
                      najlepsza_dlugosc = dlugosc
                      najlepszy_start_wartosc = wiersz1[i]
                      
      # Formatowanie wyświetlania ułamków wzorem CKE (z przecinkiem)
      srednia_str = f"{max_srednia:.2f}".replace('.', ',')
      
      print("4.4. Odpowiedź:")
      print(f"{srednia_str} {najlepsza_dlugosc} {najlepszy_start_wartosc}")
    
    solve_4_4()
  • 3

    Krok 3: Kod w języku C++

    Odpowiednik brutalnego (acz optymalnego dla 3000 elementów) przeszukiwania w C++.

    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <sstream>
    #include <iomanip>
    
    using namespace std;
    
    int main() {
      ifstream file("liczby.txt");
      string linia1;
      getline(file, linia1);
      
      vector<int> wiersz1;
      stringstream ss(linia1);
      int liczba;
      while(ss >> liczba) wiersz1.push_back(liczba);
      
      double max_srednia = -1.0;
      int najlepsza_dlugosc = 0;
      int najlepszy_start_wartosc = 0;
      
      int n = wiersz1.size();
      
      for (int i = 0; i < n; i++) {
          long long obecna_suma = 0;
          for (int j = i; j < n; j++) {
              obecna_suma += wiersz1[j];
              int dlugosc = j - i + 1;
              
              if (dlugosc >= 50) {
                  double srednia = (double)obecna_suma / dlugosc;
                  
                  if (srednia > max_srednia) {
                      max_srednia = srednia;
                      najlepsza_dlugosc = dlugosc;
                      najlepszy_start_wartosc = wiersz1[i];
                  }
              }
          }
      }
      
      cout << "4.4. Odpowiedz:" << endl;
      cout << fixed << setprecision(2) << max_srednia << " ";
      cout << najlepsza_dlugosc << " " << najlepszy_start_wartosc << endl;
      
      return 0;
    }

Matura Rozszerzona Informatyka Maj 2024

1 pkt
Zadanie 5.

Zadanie 5. (0–1 pkt)

Oceń prawdziwość podanych zdań. Zaznacz P, jeśli zdanie jest prawdziwe, albo F – jeśli jest fałszywe.

Lp.ZdaniePF
1.HTTP to protokół komunikacyjny opisujący sposób przekazywania poczty elektronicznej w internecie.
2.FTP to protokół zamiany nazw domenowych na adresy IP.
3.DHCP to protokół umożliwiający hostom uzyskanie od serwera danych konfiguracyjnych, np. adresu IP, adresu bramy sieciowej, adresu serwera DNS.
💡 Pokaż rozwiązanie krok po kroku
  • 1

    Analiza i rozwiązanie:

    1. HTTP to protokół... do poczty elektronicznej.
      FAŁSZ (F). HTTP (Hypertext Transfer Protocol) służy do przesyłania dokumentów hipertekstowych (stron WWW). Do poczty elektronicznej wykorzystuje się protokoły takie jak SMTP (wysyłanie), POP3 lub IMAP (odbieranie).

    2. FTP to protokół zamiany nazw domenowych na adresy IP.
      FAŁSZ (F). FTP (File Transfer Protocol) służy do przesyłania plików w sieci. Za zamianę nazw domenowych (np. www.google.com) na adresy IP odpowiada system DNS (Domain Name System).

    3. DHCP to protokół umożliwiający hostom uzyskanie... danych konfiguracyjnych.
      PRAWDA (P). DHCP (Dynamic Host Configuration Protocol) dokładnie do tego służy – automatycznie przydziela podłączonym urządzeniom (hostom) parametry niezbędne do działania w sieci (adres IP, maskę, bramę, adresy DNS).

Matura Rozszerzona Informatyka Maj 2024

2 pkt
Zadanie 6.

Zadanie 6. (0–2 pkt)

Wykonaj działania na liczbach zapisanych w systemie trójkowym i systemie dziewiątkowym. Wyniki podaj w systemie trójkowym.

1011123+1219=101112_3 + 121_9 = ................................................

10111231219=101112_3 - 121_9 = ................................................

💡 Pokaż rozwiązanie krok po kroku
  • 1

    Krok 1: Sprowadzenie do jednej podstawy (system trójkowy)

    Aby wykonać działania i podać wynik w systemie trójkowym, najlepiej od razu zamienić liczbę 1219121_9 na system o podstawie 3.

    Zauważ, że 9=329 = 3^2. To oznacza, że każda cyfra w systemie dziewiątkowym odpowiada dokładnie dwóm cyfrom w systemie trójkowym. Rozpiszmy to:

    • 1 (dziewiątkowo) = 01 (trójkowo)
    • 2 (dziewiątkowo) = 02 (trójkowo)
    • 1 (dziewiątkowo) = 01 (trójkowo)

    Łącząc te bloki otrzymujemy: 1219=01 02 013=102013121_9 = 01\ 02\ 01_3 = 10201_3.

  • 2

    Krok 2: Dodawanie w systemie trójkowym

    Wykonujemy dodawanie pisemne: 1011123+102013101112_3 + 10201_3. Pamiętamy, że działamy w systemie o podstawie 3, więc dostępne cyfry to tylko 0, 1 i 2. Gdy suma przekroczy 2, przenosimy "1" do następnej kolumny (np. 1 + 2 = 3 w dziesiętnym, co daje 10 w trójkowym – zapisujemy 0, przenosimy 1).

       101112
    +  10201
    --------
      112020
    Wynik dodawania:1120203112020_3
  • 3

    Krok 3: Odejmowanie w systemie trójkowym

    Teraz wykonujemy odejmowanie pisemne: 1011123102013101112_3 - 10201_3. Zapożyczenia (tzw. "pożyczki") z wyższego rzędu mają wartość podstawnika, czyli w tym wypadku pożyczamy 3, a nie 10 jak w systemie dziesiętnym.

       101112
    -  10201
    --------
      20211
    • 2 - 1 = 1
    • 1 - 0 = 1
    • 1 - 2 -> pożyczamy 1 od sąsiada po lewej. Sąsiad staje się 0, a my dostajemy +3. Mamy (1 + 3) - 2 = 2.
    • 0 - 0 = 0
    • 0 - 1 -> znów pożyczamy od lewej. Jedynka staje się 0, a my dostajemy +3. Mamy (0 + 3) - 1 = 2.
    • 0 z lewej opada, otrzymujemy końcowy wynik.
    Wynik odejmowania:20211320211_3

Matura Rozszerzona Informatyka Maj 2024

2 pkt
Zadanie 7.1.

Zadanie 7. Hurtownia

Pewna hurtownia sprzedaje jabłka. W pliku jablka.txt znajduje się 2500 wierszy z danymi dotyczącymi sprzedaży jabłek od 3 stycznia 2022 roku do 31 grudnia 2022 roku. W każdym wierszu podane są dane opisujące jedną transakcję sprzedaży, oddzielone pojedynczymi znakami tabulacji:

  • data sprzedaży zapisana w formacie rrrr-mm-dd
  • nazwa odmiany jabłka
  • kod, który określa, czy odmiana jest: L – letnia, J – jesienna czy Z – zimowa
  • numer NIP klienta (13-znakowy tekst)
  • liczba kilogramów sprzedanego towaru.
Fragment pliku jablka.txt:
2022-01-03	Jonagold	Z	128-29-15-591	470
2022-01-03	Jonagold	Z	192-09-72-275	410
2022-01-03	Jonagored	Z	140-36-11-559	242

Cena sprzedaży jednego kilograma jabłek zależy od odmiany jabłek. W pliku cennik.txt jest podana cena w złotych 1 kg jabłek każdej odmiany.

Fragment pliku cennik.txt:
Alwa	2,9
Antonowka	3,2
Cortland	3,2

Z wykorzystaniem powyższych danych oraz dostępnych narzędzi informatycznych wykonaj podane zadania. Wyniki zapisz w pliku tekstowym wyniki7.txt. Odpowiedź do każdego zadania poprzedź numerem tego zadania.

Zadanie 7.1. (0–2 pkt)

Dla każdego klienta policz, ile kupił on łącznie (we wszystkich swoich transakcjach) kilogramów jabłek odmian zimowych. Podaj numery NIP trzech klientów, którzy kupili najwięcej jabłek odmian zimowych (Z), oraz podaj dla każdego z nich liczbę kilogramów jabłek odmian zimowych przez nich kupionych.

💡 Pokaż rozwiązanie krok po kroku
  • 1

    Krok 1: Praca w MS Access (Kwerenda grupująca)

    Zadanie opiera się wyłącznie na danych z jednej tabeli (jablka), co czyni je bardzo prostym w programie MS Access.

    1. Zaimportuj plik jablka.txt do bazy danych. Zadbaj o poprawne typy danych – liczba kilogramów musi być liczbą całkowitą, aby można było ją sumować.
    2. Utwórz nowy Projekt kwerendy i dodaj do niego tabelę jablka.
    3. Dodaj pola NIP, kod oraz liczba_kg do siatki kwerendy.
    4. Włącz przycisk Sumy (Σ\Sigma) w górnym menu.
    5. Skonfiguruj wiersz "Suma" dla poszczególnych kolumn:

      • Dla pola NIP: pozostaw Grupuj według.
      • Dla pola kod: zmień na Warunek i w polu Kryteria wpisz "Z" (odfiltrowanie tylko odmian zimowych). Odznacz widoczność tego pola.
      • Dla pola liczba_kg: zmień na Suma i ustaw sortowanie na Malejąco.
    6. Uruchom kwerendę i odczytaj pierwsze trzy rekordy z najwyższymi wynikami.
  • 2

    Krok 2: Alternatywa - Język SQL

    To samo zadanie zapisane w czystym języku SQL. Używamy klauzuli TOP 3, aby od razu ograniczyć wynik do żądanej w zadaniu trójki klientów.

    SELECT TOP 3 NIP, SUM(liczba_kg) AS Suma_Zimowych
    FROM jablka
    WHERE kod = 'Z'
    GROUP BY NIP
    ORDER BY SUM(liczba_kg) DESC;
  • 3

    Krok 3: Alternatywa - Język Python

    Jeśli wolisz programowanie, możesz rozwiązać to zadanie budując słownik zliczający kilogramy, a następnie posortować go po wartościach malejąco.

    def solve_7_1():
      zakupy_klientow = {}
      
      with open('jablka.txt', 'r') as file:
          for line in file:
              parts = line.strip().split('\t')
              if len(parts) >= 5:
                  kod = parts[2]
                  nip = parts[3]
                  kilogramy = int(parts[4])
                  
                  # Interesują nas tylko odmiany zimowe (Z)
                  if kod == 'Z':
                      zakupy_klientow[nip] = zakupy_klientow.get(nip, 0) + kilogramy
                      
      # Sortowanie słownika malejąco po zsumowanych kilogramach
      posortowani = sorted(zakupy_klientow.items(), key=lambda item: item[1], reverse=True)
      
      print("7.1. Wynik (Top 3):")
      for i in range(3):
          print(f"NIP: {posortowani[i][0]} | Suma: {posortowani[i][1]} kg")
    
    solve_7_1()

Matura Rozszerzona Informatyka Maj 2024

2 pkt
Zadanie 7.2.

Podpunkt 7.2. (0–2 pkt)

Przychód z pojedynczej sprzedaży to cena sprzedaży jednego kilograma jabłek pomnożona przez liczbę kilogramów. Podaj całkowity przychód hurtowni uzyskany w całym okresie. Podaj nazwę odmiany jabłek, która dała największy przychód.

💡 Pokaż rozwiązanie krok po kroku
  • 1

    Krok 1: Konstrukcja zapytań w języku SQL

    Musimy połączyć tabelę jablka z tabelą cennik po nazwie odmiany, aby móc pomnożyć sprzedane kilogramy przez cenę. Wymagane są dwie informacje, więc najwygodniej przygotować dwa osobne zapytania.

    Zapytanie 1: Całkowity przychód hurtowni
    SELECT SUM(jablka.liczba_kg * cennik.cena) AS Calkowity_Przychod
    FROM jablka INNER JOIN cennik ON jablka.odmiana = cennik.odmiana;
    Zapytanie 2: Odmiana z największym przychodem

    Grupujemy po odmianie, sumujemy przychód, sortujemy malejąco i wybieramy pierwszy rekord klauzulą TOP 1.

    SELECT TOP 1 jablka.odmiana, SUM(jablka.liczba_kg * cennik.cena) AS Przychod
    FROM jablka INNER JOIN cennik ON jablka.odmiana = cennik.odmiana
    GROUP BY jablka.odmiana
    ORDER BY SUM(jablka.liczba_kg * cennik.cena) DESC;
  • 2

    Krok 2: Alternatywa - Język Python

    W Pythonie musimy pamiętać o zamianie przecinków na kropki podczas wczytywania cennika, aby poprawnie rzutować tekst na typ zmiennoprzecinkowy (float).

    def solve_7_2():
      # 1. Wczytanie cennika do słownika
      cennik = {}
      with open('cennik.txt', 'r') as f:
          for line in f:
              parts = line.strip().split('\t')
              if len(parts) == 2:
                  odmiana = parts[0]
                  # Zamiana polskiego przecinka na kropkę!
                  cena = float(parts[1].replace(',', '.'))
                  cennik[odmiana] = cena
    
      # 2. Przetwarzanie transakcji
      calkowity_przychod = 0
      przychod_odmiany = {}
    
      with open('jablka.txt', 'r') as f:
          for line in f:
              parts = line.strip().split('\t')
              if len(parts) >= 5:
                  odmiana = parts[1]
                  kilogramy = int(parts[4])
                  
                  cena_za_kg = cennik.get(odmiana, 0)
                  przychod_z_transakcji = kilogramy * cena_za_kg
                  
                  calkowity_przychod += przychod_z_transakcji
                  przychod_odmiany[odmiana] = przychod_odmiany.get(odmiana, 0) + przychod_z_transakcji
    
      # 3. Znalezienie odmiany z największym przychodem
      najlepsza_odmiana = max(przychod_odmiany.items(), key=lambda x: x[1])
    
      print("7.2. Całkowity przychód: {:.2f} zł".format(calkowity_przychod))
      print(f"7.2. Najlepsza odmiana: {najlepsza_odmiana[0]} (Przychód: {najlepsza_odmiana[1]:.2f} zł)")
    
    solve_7_2()

Matura Rozszerzona Informatyka Maj 2024

3 pkt
Zadanie 7.3.

Podpunkt 7.3. (0–3 pkt)

Wykonaj zestawienie, w którym dla każdego miesiąca roku 2022 podasz nazwę najbardziej popularnej odmiany w tym miesiącu, czyli takiej, której w danym miesiącu sprzedano najwięcej.

Na podstawie wykonanego zestawienia utwórz wykres kolumnowy ilustrujący wielkości sprzedaży najpopularniejszych odmian jabłek w poszczególnych miesiącach.

Pamiętaj o czytelnym opisie wykresu – na osi X umieść dla każdego miesiąca jego nazwę połączoną z nazwą najbardziej popularnej odmiany w tym miesiącu, dodaj opis osi Y i tytuł wykresu.

💡 Pokaż rozwiązanie krok po kroku
  • 1

    Krok 1: Architektura logiczna rozwiązania

    Zadanie polega na znalezieniu "maksimum w grupach". Wymaga to wykonania trójetapowej agregacji (którą można zrealizować w bazie danych lub w Pythonie), a następnie przeniesienia wyników do Excela w celu wygenerowania wykresu.

  • 2

    Krok 2: Pozyskanie danych zestawienia (Python)

    Python wygeneruje nam gotowy raport w formie tekstowej, który bez problemu wkleimy do Excela jako źródło wykresu. Formatujemy oś X z góry (Miesiąc-Odmiana).

    def solve_7_3():
      # Słownik zagnieżdżony: sprzedaz[miesiac][odmiana] = suma_kg
      sprzedaz = {str(i).zfill(2): {} for i in range(1, 13)}
      
      with open('jablka.txt', 'r') as f:
          for line in f:
              parts = line.strip().split('\t')
              if len(parts) >= 5:
                  data = parts[0]
                  miesiac = data[5:7] # Wyciągamy 'MM' z 'YYYY-MM-DD'
                  odmiana = parts[1]
                  kg = int(parts[4])
                  
                  sprzedaz[miesiac][odmiana] = sprzedaz[miesiac].get(odmiana, 0) + kg
                  
      # Znalezienie najpopularniejszej odmiany w każdym miesiącu
      print("Dane do wklejenia do arkusza (Oś X \t Oś Y):")
      print("Miesiac_Odmiana\tSprzedaz_kg")
      
      for miesiac in sorted(sprzedaz.keys()):
          dane_miesiaca = sprzedaz[miesiac]
          if dane_miesiaca:
              # Znajdź odmianę z maksymalną wartością
              najlepsza_odmiana = max(dane_miesiaca.items(), key=lambda x: x[1])
              nazwa_odmiany = najlepsza_odmiana[0]
              max_kg = najlepsza_odmiana[1]
              
              # Wypisanie zgodnie z wytycznymi na osi X
              etykieta_x = f"{miesiac}-{nazwa_odmiany}"
              print(f"{etykieta_x}\t{max_kg}")
    
    solve_7_3()
  • 3

    Krok 3: Kwerendy SQL dla MS Access (Alternatywa)

    Jeśli wolisz wyciągać dane SQL-em, musisz zapisać podrzędne kwerendy:

    1. Zsumowanie kilogramów: Zapisz kwerendę pod nazwą np. Suma_Miesieczna.

      SELECT MONTH(data_sprzedazy) AS Miesiac, odmiana, SUM(liczba_kg) AS SumaKG 
      FROM jablka GROUP BY MONTH(data_sprzedazy), odmiana;
    2. Znalezienie maksimum: Zapisz kwerendę pod nazwą np. Max_Miesieczny.

      SELECT Miesiac, MAX(SumaKG) AS MaxKG 
      FROM Suma_Miesieczna GROUP BY Miesiac;
    3. Połączenie wyników do wykresu: Tworzymy finalną etykietę łącząc miesiąc i odmianę (w Accessie służy do tego znak &).

      SELECT S.Miesiac & "-" & S.odmiana AS EtykietaX, M.MaxKG AS OśY
      FROM Suma_Miesieczna AS S INNER JOIN Max_Miesieczny AS M 
      ON S.Miesiac = M.Miesiac AND S.SumaKG = M.MaxKG;
  • 4

    Krok 4: Generowanie wykresu w Arkuszu Kalkulacyjnym (Excel)

    Ostatni etap to wizualizacja zgodnie z poleceniem:

    • Skopiuj wyniki wygenerowane z Kliku 2 lub 3 do Excela (dwie kolumny).
    • Zaznacz obie kolumny, przejdź do zakładki Wstawianie i wybierz standardowy Wykres kolumnowy.
    • Zmień tytuł wykresu na czytelny, np. "Wielkość sprzedaży najpopularniejszych odmian w miesiącach 2022 roku".
    • Dodaj tytuł osi Y (kliknij znak "+" obok wykresu -> Tytuły osi) i wpisz np. "Sprzedaż [kg]". Oś X automatycznie zaczyta przygotowane etykiety w formacie np. 01-Jonagold.

Matura Rozszerzona Informatyka Maj 2024

3 pkt
Zadanie 7.4.

Zadanie 7.4. (0–3 pkt)

Hurtownia ma system premiowania klientów hurtowych. Klient otrzymuje przy zakupie rabat, którego wysokość zależy od łącznej ilości jabłek zakupionych do tej pory przez tego klienta, wliczając w to jabłka zakupione w bieżącej transakcji.

Wysokość rabatu za każdy kilogram w bieżącej transakcji wynosi:

  • 5 gr, jeśli klient dotychczas zakupił co najmniej 15 000 kg, ale mniej niż 20 000 kg
  • 10 gr, jeśli klient dotychczas zakupił co najmniej 20 000 kg.

Podaj, w ilu transakcjach hurtownia udzieliła rabatu, oraz podaj łączną wartość tych rabatów w złotych.

Przykład:

Załóżmy, że przed 1.04.2022 klient z NIP 128-29-15-591 zakupił łącznie 10 000 kg jabłek, klient 192-09-72-275 nabył 14 900 kg, a klient 140-36-11-559 – kupił 19 900 kg. Wtedy dla przykładowych danych 1.04.2022:

2022-04-01    Jonagold    Z    128-29-15-591    470
2022-04-01    Jonagold    Z    192-09-72-275    410
2022-04-01    Jonagored   Z    140-36-11-559    242
  • pierwszy klient, po dokonaniu transakcji 1.04.2022, będzie miał już 10 470 kg zakupionych jabłek i dla tej transakcji jeszcze nie należy się rabat
  • drugi klient, po dokonaniu transakcji 1.04.2022, będzie miał już 15 310 kg zakupionych jabłek, czyli podczas tej transakcji otrzyma 5 gr rabatu na każdy kilogram kupowany tego dnia jabłek (5 gr * 410 = 20,50 zł rabatu)
  • trzeci klient, po dokonaniu transakcji 1.04.2022, będzie miał już 20 142 kg zakupionych jabłek i podczas tej transakcji otrzyma 10 gr rabatu za każdy kilogram (10 gr * 242 = 24,20 zł rabatu).
💡 Pokaż rozwiązanie krok po kroku
  • 1

    Krok 1: Architektura rozwiązania

    Aby wyliczyć rabat, musimy dla każdego wiersza w pliku (które są ułożone chronologicznie) znać stan konta danego klienta przed sprawdzeniem warunku, ale już z uwzględnieniem bieżącego zakupu.

    Najlepszą strukturą do śledzenia tego na bieżąco jest słownik (mapa) w Pythonie, gdzie kluczem będzie NIP klienta, a wartością – dotychczasowa, narastająca suma zakupionych kilogramów. Przechodząc linijka po linijce, aktualizujemy sumę, a następnie sprawdzamy, w jakie progi (5 gr czy 10 gr) wpada klient.

  • 2

    Krok 2: Logika przeliczania groszy na złote

    Zadanie prosi o podanie wyniku w złotówkach. Zamiast operować na ułamkach od samego początku, dobrą praktyką jest przeliczanie kwoty podczas samego mnożenia: 5 gr=0.05 PLN5 \text{ gr} = 0.05 \text{ PLN} oraz 10 gr=0.10 PLN10 \text{ gr} = 0.10 \text{ PLN}.

  • 3

    Krok 3: Implementacja w Pythonie

    def solve_7_4():
      # Słownik do śledzenia historii zakupów: {nip: suma_kg}
      historia_zakupow = {}
      
      liczba_transakcji_z_rabatem = 0
      laczna_wartosc_rabatow_pln = 0.0
    
      with open('jablka.txt', 'r') as file:
          for line in file:
              parts = line.strip().split('\t')
              if len(parts) >= 5:
                  nip = parts[3]
                  kg_w_transakcji = int(parts[4])
                  
                  # Aktualizujemy sumę klienta ZANIM sprawdzimy progi
                  historia_zakupow[nip] = historia_zakupow.get(nip, 0) + kg_w_transakcji
                  biezaca_suma = historia_zakupow[nip]
                  
                  # Sprawdzanie progów rabatowych
                  if biezaca_suma >= 20000:
                      # Rabat 10 groszy (0.10 zł) za każdy kg z bieżącej transakcji
                      wartosc_rabatu = kg_w_transakcji * 0.10
                      liczba_transakcji_z_rabatem += 1
                      laczna_wartosc_rabatow_pln += wartosc_rabatu
                      
                  elif biezaca_suma >= 15000:
                      # Rabat 5 groszy (0.05 zł) za każdy kg z bieżącej transakcji
                      wartosc_rabatu = kg_w_transakcji * 0.05
                      liczba_transakcji_z_rabatem += 1
                      laczna_wartosc_rabatow_pln += wartosc_rabatu
    
      print(f"7.4. Liczba transakcji z rabatem: {liczba_transakcji_z_rabatem}")
      
      # Formatowanie wyświetlania ułamków wzorem CKE (z przecinkiem)
      rabaty_str = f"{laczna_wartosc_rabatow_pln:.2f}".replace('.', ',')
      print(f"7.4. Łączna wartość rabatów: {rabaty_str} zł")
    
    solve_7_4()

Matura Rozszerzona Informatyka Maj 2024

0
Zadanie 8.

Zadanie 8. Rejestr wykroczeń

W trzech plikach tekstowych o nazwach: kierowcy.txt, taryfikator.txt, rejestr.txt, zapisano dane związane z przekroczeniem dozwolonych prędkości pojazdów na pewnej trasie w okresie 2023-01-01 – 2023-12-30 (wszystkie dane są fikcyjne i wygenerowane na potrzeby zadania). Pierwszy wiersz każdego z plików jest wierszem nagłówkowym, a dane w wierszach rozdzielono znakiem średnika.

Plik o nazwie kierowcy.txt zawiera informacje o 1000 osobach będących właścicielami samochodów. W każdym wierszu znajduje się:

  • IdOsoby – identyfikator kierowcy
  • Imie – imię
  • Nazwisko – nazwisko
  • NrRejestracyjny – numer rejestracyjny samochodu.
Przykład:
IdOsoby;Imie;Nazwisko;NrRejestracyjny
1;Echo;Ayala;FVX4190
2;Nolan;Stein;DUG5882
3;Lee;Joseph;TBG6984

Plik o nazwie taryfikator.txt zawiera informacje o 6 rodzajach wykroczeń związanych z przekroczeniem prędkości. W każdym wierszu znajdują się:

  • IdWykroczenia – identyfikator wykroczenia
  • Wykroczenie – opis wykroczenia
  • Punkty – liczba punktów karnych za dane wykroczenie
  • Kwota – kwota mandatu, jaką należy zapłacić za to wykroczenie.
Przykład:
IdWykroczenia;Wykroczenie;Punkty;Kwota
1;Przekroczenie predkosci do 10 km/h;0;50
2;Przekroczenie predkosci od 11 do 20 km/h;2;100
3;Przekroczenie predkosci od 21 do 30 km/h;4;200
4;Przekroczenie predkosci od 31 do 40 km/h;6;300
5;Przekroczenie predkosci od 41 do 50 km/h;8;400
6;Przekroczenie predkosci od 51 km/h;10;500

Plik o nazwie rejestr.txt zawiera 5000 zarejestrowanych wykroczeń związanych z przekroczeniem prędkości. W każdym wierszu znajdują się:

  • IdZdarzenia – identyfikator zdarzenia
  • Data – data zdarzenia w formacie rrrr-mm-dd
  • IdOsoby – identyfikator kierowcy
  • IdWykroczenia – identyfikator wykroczenia.
Przykład:
IdZdarzenia;Data;IdOsoby;IdWykroczenia
1;2023-01-01;617;1
2;2023-01-01;956;4
💡 Pokaż rozwiązanie krok po kroku

    Matura Rozszerzona Informatyka Maj 2024

    2 pkt
    Zadanie 8.1.

    Zadanie 8.1. (0–2 pkt)

    Podaj imię i nazwisko kierowcy, dla którego suma kwot za wszystkie mandaty była największa, oraz podaj tę największą sumę. Jest tylko jeden taki kierowca.

    💡 Pokaż rozwiązanie krok po kroku
    • 1

      Krok 1: Rozwiązanie w języku SQL (MS Access)

      Aby powiązać kierowcę z kwotami mandatów, musimy złączyć wszystkie trzy tabele: kierowcy łączymy z rejestr po polu IdOsoby, a następnie wynik łączymy z tabelą taryfikator po polu IdWykroczenia.

      Grupujemy dane po kierowcy, sumujemy pole Kwota, sortujemy wynik malejąco i wybieramy pierwszy rekord.

      SELECT TOP 1 k.Imie, k.Nazwisko, SUM(t.Kwota) AS SumaKwot
      FROM (kierowcy AS k
      INNER JOIN rejestr AS r ON k.IdOsoby = r.IdOsoby)
      INNER JOIN taryfikator AS t ON r.IdWykroczenia = t.IdWykroczenia
      GROUP BY k.IdOsoby, k.Imie, k.Nazwisko
      ORDER BY SUM(t.Kwota) DESC;
    • 2

      Krok 2: Alternatywa - Język Python

      def solve_8_1():
        # 1. Wczytanie taryfikatora (IdWykroczenia -> Kwota)
        taryfikator = {}
        with open('taryfikator.txt', 'r') as f:
            next(f) # pominięcie nagłówka
            for line in f:
                parts = line.strip().split(';')
                taryfikator[parts[0]] = int(parts[3])
                
        # 2. Sumowanie kwot dla IdOsoby na podstawie rejestru
        kary_kierowcow = {}
        with open('rejestr.txt', 'r') as f:
            next(f)
            for line in f:
                parts = line.strip().split(';')
                id_osoby = parts[2]
                id_wykroczenia = parts[3]
                kary_kierowcow[id_osoby] = kary_kierowcow.get(id_osoby, 0) + taryfikator[id_wykroczenia]
                
        # 3. Znalezienie IdOsoby z największą sumą
        najgorszy_kierowca_id = max(kary_kierowcow, key=kary_kierowcow.get)
        max_kwota = kary_kierowcow[najgorszy_kierowca_id]
        
        # 4. Odczytanie danych z pliku kierowcy
        with open('kierowcy.txt', 'r') as f:
            next(f)
            for line in f:
                parts = line.strip().split(';')
                if parts[0] == najgorszy_kierowca_id:
                    print(f"8.1. Wynik: {parts[1]} {parts[2]}, Suma: {max_kwota} zł")
                    break
      
      solve_8_1()

    Matura Rozszerzona Informatyka Maj 2024

    2 pkt
    Zadanie 8.2.

    Zadanie 8.2. (0–2 pkt)

    W którym miesiącu kierowcy otrzymali najmniej punktów karnych (łącznie) za wykroczenia polegające na przekroczeniu dozwolonej prędkości o więcej niż 20 km/h (wykroczenia o identyfikatorach od 3 do 6)? Podaj miesiąc oraz łączną liczbę punktów karnych z tego miesiąca.

    💡 Pokaż rozwiązanie krok po kroku
    • 1

      Krok 1: Rozwiązanie w języku SQL (MS Access)

      Tym razem łączymy rejestr tylko z taryfikatorem (ponieważ punkty są w taryfikatorze, a daty w rejestrze). Filtrujemy identyfikatory wykroczeń przy użyciu operatora IN (lub BETWEEN 3 AND 6), grupujemy wyniki po wyciągniętym miesiącu za pomocą funkcji MONTH() i sortujemy rosnąco.

      SELECT TOP 1 MONTH(r.Data) AS Miesiac, SUM(t.Punkty) AS LaczniePunktow
      FROM rejestr AS r
      INNER JOIN taryfikator AS t ON r.IdWykroczenia = t.IdWykroczenia
      WHERE r.IdWykroczenia IN (3, 4, 5, 6)
      GROUP BY MONTH(r.Data)
      ORDER BY SUM(t.Punkty) ASC;
    • 2

      Krok 2: Alternatywa - Język Python

      def solve_8_2():
        # Słownik: IdWykroczenia -> Punkty (tylko dla id 3, 4, 5, 6)
        punkty_za_wykroczenia = {}
        with open('taryfikator.txt', 'r') as f:
            next(f)
            for line in f:
                parts = line.strip().split(';')
                id_w = parts[0]
                if id_w in ['3', '4', '5', '6']:
                    punkty_za_wykroczenia[id_w] = int(parts[2])
                    
        # Słownik zliczający: Miesiac -> Suma Punktów
        punkty_miesiace = {}
        with open('rejestr.txt', 'r') as f:
            next(f)
            for line in f:
                parts = line.strip().split(';')
                data = parts[1]
                id_w = parts[3]
                
                # Jeśli wykroczenie nas interesuje
                if id_w in punkty_za_wykroczenia:
                    miesiac = data[5:7] # Wyciągamy dwucyfrowy miesiąc
                    punkty = punkty_za_wykroczenia[id_w]
                    punkty_miesiace[miesiac] = punkty_miesiace.get(miesiac, 0) + punkty
                    
        # Znalezienie najmniejszej wartości
        najlepszy_miesiac = min(punkty_miesiace, key=punkty_miesiace.get)
        min_punkty = punkty_miesiace[najlepszy_miesiac]
        
        print(f"8.2. Wynik: Miesiąc {najlepszy_miesiac}, Punktów: {min_punkty}")
      
      solve_8_2()

    Matura Rozszerzona Informatyka Maj 2024

    3 pkt
    Zadanie 8.3.

    Zadanie 8.3. (0–3 pkt)

    Wykonaj zestawienie numerów rejestracyjnych samochodów wraz z imionami i nazwiskami ich właścicieli, którzy nie figurują w rejestrze wykroczeń. Zestawienie posortuj alfabetycznie według numerów rejestracyjnych samochodów.

    💡 Pokaż rozwiązanie krok po kroku
    • 1

      Krok 1: Rozwiązanie w języku SQL (MS Access)

      Jest to klasyczny problem poszukiwania rekordów z jednej tabeli, których brakuje w drugiej. Najwygodniej (i najbardziej czytelnie) jest zastosować podzapytanie z klauzulą NOT IN. Szukamy osób w tabeli kierowcy, których IdOsoby nie znajduje się na liście identyfikatorów w tabeli rejestr.

      SELECT NrRejestracyjny, Imie, Nazwisko
      FROM kierowcy
      WHERE IdOsoby NOT IN (SELECT IdOsoby FROM rejestr)
      ORDER BY NrRejestracyjny ASC;

      *Uwaga: Innym dopuszczalnym sposobem w SQL jest użycie LEFT JOIN pomiędzy kierowcami a rejestrem i wyfiltrowanie WHERE rejestr.IdOsoby IS NULL. Obie metody dadzą poprawny wynik.

    • 2

      Krok 2: Alternatywa - Język Python

      W Pythonie wyciągniemy wszystkie identyfikatory kierowców ukaranych do zbioru (ang. set), a następnie przefiltrujemy tabelę kierowców, ignorując tych, których identyfikator jest w tym zbiorze. Na koniec posortujemy listę "czystych" kierowców.

      def solve_8_3():
        # 1. Zbiór ID ukaranych kierowców (używamy seta dla szybkości)
        ukarani = set()
        with open('rejestr.txt', 'r') as f:
            next(f)
            for line in f:
                parts = line.strip().split(';')
                ukarani.add(parts[2])
                
        # 2. Wyławiamy wzorowych kierowców
        wzorowi_kierowcy = []
        with open('kierowcy.txt', 'r') as f:
            next(f)
            for line in f:
                parts = line.strip().split(';')
                id_osoby = parts[0]
                if id_osoby not in ukarani:
                    # Dołączamy jako krotkę: (NrRej, Imie, Nazwisko)
                    wzorowi_kierowcy.append((parts[3], parts[1], parts[2]))
                    
        # 3. Sortowanie alfabetyczne po numerze rejestracyjnym (pierwszy element krotki)
        wzorowi_kierowcy.sort()
        
        print("8.3. Wzorowi kierowcy (pierwsze 5 wyników):")
        for nr, imie, nazwisko in wzorowi_kierowcy[:5]:
            print(f"{nr} | {imie} {nazwisko}")
            
        print(f"...(łącznie {len(wzorowi_kierowcy)} kierowców)")
      
      solve_8_3()

    Matura Rozszerzona Informatyka Maj 2024

    2 pkt
    Zadanie 8.4.

    Zadanie 8.4. (0–2 pkt)

    Baza danych rejestru wykroczeń została zmodyfikowana. Dodano nową tabelę Fotoradar, wraz z polami IdFotoradaru, Miejscowosc i DozwolonaPredkosc. Natomiast do tabeli Rejestr zostało dodane pole IdFotoradaru, w którym dla każdego rekordu zapisano identyfikator tego fotoradaru, który zarejestrował dane wykroczenie.

    Załóżmy, że w bazie istnieją fotoradary, które nie zarejestrowały żadnych wykroczeń. Zapisz w języku SQL zapytanie, w wyniku którego otrzymasz identyfikatory tych fotoradarów.

    💡 Pokaż rozwiązanie krok po kroku
    • 1

      Krok 1: Analiza problemu

      Zadanie polega na znalezieniu rekordów w tabeli Fotoradar, które nie mają swojego odpowiednika (powiązania) w tabeli Rejestr. Jest to klasyczny problem poszukiwania "osieroconych" lub "nieużywanych" rekordów, bardzo podobny logicznie do zadania 8.3.

      Można to rozwiązać na dwa główne sposoby akceptowane na maturze: za pomocą podzapytania z klauzulą NOT IN lub za pomocą złączenia lewostronnego (LEFT JOIN).

    • 2

      Krok 2: Rozwiązanie 1 – Podzapytanie (Najbardziej intuicyjne)

      Wybieramy identyfikatory z tabeli fotoradarów, pod warunkiem, że nie znajdują się one na liście identyfikatorów wyciągniętych z rejestru.

      SELECT IdFotoradaru 
      FROM Fotoradar 
      WHERE IdFotoradaru NOT IN (SELECT IdFotoradaru FROM Rejestr);
    • 3

      Krok 3: Rozwiązanie 2 – Złączenie (LEFT JOIN)

      Bierzemy wszystkie fotoradary i próbujemy dopasować do nich wpisy z rejestru. Jeśli fotoradar niczego nie zarejestrował, w miejscach danych z rejestru pojawią się wartości puste (NULL). Wystarczy więc odfiltrować właśnie te puste wartości.

      SELECT f.IdFotoradaru 
      FROM Fotoradar AS f LEFT JOIN Rejestr AS r 
      ON f.IdFotoradaru = r.IdFotoradaru 
      WHERE r.IdFotoradaru IS NULL;

    Problemy z algorytmem lub Excelem?

    Arkusz to nie wszystko. Systematyzuj swoją wiedzę rozwiązując zadania i czytając opracowania maturalne z naszej bazy wiedzy.

    Pytania o arkusz z Informatyki

    Ile trwa Matura z Informatyki?

    Egzamin maturalny z informatyki na poziomie rozszerzonym trwa 210 minut i odbywa się w całości przy stanowisku komputerowym.

    Gdzie znaleźć kody źródłowe i rozwiązania do arkusza Matura Rozszerzona Informatyka 2024 Maj?

    Pełne rozwiązania krok po kroku (w tym kody źródłowe w Python/C++, kwerendy SQL i formuły Excel) znajdują się na tej stronie powyżej. Każde zadanie jest szczegółowo omówione.

    Czy mogę pobrać pliki (Dane.zip) i ten arkusz w formacie PDF?

    Tak, linki do oficjalnego arkusza CKE w formacie PDF oraz paczki z plikami tekstowymi najczęściej znajdują się na górze tej strony.

    ProKorepetycje © 2026

    Wszystkie arkusze CKE