{"paper":{"id":"informatyka-2019-maj-matura-rozszerzona","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","variant":null,"exam_pdf":"informatyka-2019-maj-matura-rozszerzona/informatyka-2019-maj-matura-rozszerzona.pdf","key_pdf":"informatyka-2019-maj-matura-rozszerzona-odpowiedzi/informatyka-2019-maj-matura-rozszerzona-odpowiedzi.pdf","question_count":23,"source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},"questions":[{"id":"informatyka-2019-maj-matura-rozszerzona/zad/1","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"1","points":null,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Zadanie 1. Ulubione liczby\nMałgosia i Jaś lubią liczby. Małgosia lubi liczby nieparzyste, a Jaś lubi liczby parzyste. Każde\nz dzieci zapisało po kilka spośród swoich ulubionych liczb na jednej wspólnej kartce. Najpierw\nMałgosia zapisała wszystkie swoje liczby, a potem Jaś dopisał swoje.","answer":null,"answer_text":"102","solution":null,"image":"img/informatyka-2019-maj-matura-rozszerzona/zad-1.webp","solution_image":null,"topics":null,"page_from":2,"source":"ocr","answer_source":null,"answer_text_source":"ocr","solution_source":null,"text_source":"ocr","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/1.1","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"1.1","points":5,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Zadanie 1.1. (0-5)\nNapisz algorytm (w postaci listy kroków, w pseudokodzie lub w wybranym języku\nprogramowania), który dla danego ciągu liczb zapisanych przez dzieci znajdzie pierwszą liczbę\nzapisaną przez Jasia. Zakładamy, że każde z dzieci zapisało co najmniej jedną liczbę.\nPrzy ocenie będzie brana pod uwagę złożoność czasowa Twojego algorytmu. Maksymalną\nliczbę punktów uzyskasz za algorytm o złożoności lepszej niż liniowa.\nUwaga: W zapisie algorytmu możesz wykorzystać tylko operacje arytmetyczne (dodawanie,\nodejmowanie, mnożenie, dzielenie, dzielenie całkowite, reszta z dzielenia), instrukcje\nporównania, instrukcje sterujące i przypisania do zmiennych lub samodzielnie napisane\nfunkcje, wykorzystujące wyżej wymienione operacje.\nSpecyfikacja:\nDane:\nn\n- liczba całkowita większa od 1\nA[1 n]\n- tablica zawierająca ciąg n liczb zapisanych przez dzieci (najpierw\nwszystkie liczby nieparzyste, a potem wszystkie liczby parzyste)\nWynik:\nw\n- pierwsza od lewej parzysta liczba w tablicy A\nPrzykład:\nDane:\nn = 10\nA[1 n] = ሼ5, 99, 3, 7, 111, 13, 4, 24, 4, 8ሽ\nWynik:\nw = 4\nMIN_1R","answer":null,"answer_text":"Zadanie 1.1. (0-5)\nWymagania ogólne\nWymagania szczegółowe\nIII. Rozwiązywanie problemów\ni podejmowanie decyzji […]\nz zastosowaniem podejścia algorytmicznego.\n5. Rozwiązywanie problemów\ni podejmowanie decyzji […], stosowanie\npodejścia algorytmicznego.\nZdający:\n1) analizuje, modeluje i rozwiązuje sytuacje\nproblemowe z różnych dziedzin;\n2) stosuje podejście algorytmiczne do\nrozwiązywania problemu;\n4) dobiera efektywny algorytm do\nrozwiązania sytuacji problemowej\ni zapisuje go w wybranej notacji;\n5) posługuje się podstawowymi technikami\nalgorytmicznymi;\n11) opisuje podstawowe algorytmy\ni stosuje: […]\nb) algorytmy wyszukiwania\ni porządkowania (sortowania), […]\n16) opisuje własności algorytmów na\npodstawie ich analizy;\n17) ocenia zgodność algorytmu ze\nspecyfikacją problemu;\n18) oblicza liczbę operacji wykonywanych\nprzez algorytm;\n20) bada efektywność komputerowych\nrozwiązań problemów.\nSchemat punktowania\n5 p. - za poprawny algorytm o złożoności czasowej lepszej niż liniowa, w tym:\n1 p. - prawidłowy warunek pętli,\n1 p. - prawidłowe wyznaczenie podziału ciągu liczb,\n1 p. - prawidłowe wyznaczenie początku podciągu liczb,\n1 p. - prawidłowe wyznaczenie końca podciągu liczb,\n1 p. - prawidłowe wyznaczenie pierwszego elementu parzystego w A[] (lub jego indeksu).\n3 p. - za poprawny algorytm o złożoności czasowej liniowej, w tym:\n1 p. - za prawidłowy przebieg pętli,\n1 p. - za sprawdzenie warunku (parzystości liczby),\n1 p. - prawidłowe wyznaczenie pierwszego elementu parzystego w A[] (lub jego\nindeksu).\n0 p. - za podanie odpowiedzi błędnej albo brak odpowiedzi.\nUwaga: Za każde inne poprawne rozwiązanie o złożoności lepszej niż liniowa przyznajemy\nmaksymalnie 5 punktów, a o złożoności liniowej - maksymalnie 3 punkty.\nPrzykładowe rozwiązania\nAlgorytm o złożoności logarytmicznej - wyszukiwanie binarne (w języku c++)\np ←1\nk ← n\ndopóki p <k wykonuj\ns ← (p + k) div 2\njeżeli ( A[s] mod 2 = 1 )\np ← s + 1\nw przeciwnym przypadku\nk ← s\nw ← A[p]\nAlgorytm o złożoności logarytmicznej - wyszukiwanie binarne (w języku Python)\ndef szukaj_bin(A):\nlewy, prawy = 1, n\nwhile lewy < prawy:\nśrodkowy = (lewy + prawy) // 2\nif A[środkowy] % 2 != 0:\nlewy = środkowy + 1\nelse:\nprawy = środkowy\nreturn prawy\nAlgorytm o złożoności liniowej - wyszukiwanie liniowe\np ←1\ndopóki A[p] mod 2 = 1 wykonuj\np ← p + 1\nw ← A[p]\nAlgorytm o złożoności pierwiastkowej\nint pier(int n){\nint i = 1;\nwhile(i * i < n) i++;\nif(i * i > n) i--;\nreturn i;\n}\nint wyszukiwanie(){\nint p = pier(n) - 1;\nint i = p;\nwhile(i < n)\n{\nif(A[i] % 2 == 0){\nint j = i;\nwhile(A[j] % 2 == 0) j--;\nreturn j + 1;\n}\nif(i + p > n) i = n - 1;\ni += p;\n}\n}\nw=A[wyszukiwanie()];","solution":"## Poprawna odpowiedź\n\n**Algorytm wyszukiwania binarnego (zmodyfikowanego) - złożoność O(log n):**\n\np ← 1\nk ← n\ndopóki p < k wykonuj\ns ← (p + k) div 2\njeżeli A[s] mod 2 = 1\np ← s + 1\nw przeciwnym przypadku\nk ← s\nw ← A[p]\n\n## Sposób 1 - wyszukiwanie binarne O(log n) [maksymalna punktacja]\n\n**Kluczowa obserwacja:** ciąg ma strukturę `[nieparzyste, nieparzyste, , parzyste, parzyste, ]`. Szukamy **granicy** między częścią nieparzystą a parzystą - czyli pierwszego indeksu z liczbą parzystą. Tak posortowany ciąg (najpierw 1, potem 0 dla parzystości) idealnie nadaje się do **wyszukiwania binarnego** - szukamy pierwszego wystąpienia 0.\n\n**Idea:** utrzymujemy przedział `[p, k]` zawierający szukaną pierwszą parzystą:\n- środek `s = (p+k) div 2`.\n- jeśli `A[s]` jest nieparzyste (mod 2 = 1) → granica jest po prawej: `p ← s+1`.\n- jeśli `A[s]` jest parzyste → granica może być w `s` lub wcześniej: `k ← s` (NIE `s-1`, bo `s` to kandydat!).\n- pętla kończy się gdy `p = k` → `A[p]` to pierwsza parzysta.\n\n**Python:**\n```python\ndef pierwsza_parzysta(A, n):\np, k = 0, n - 1 # indeksowanie od 0 w Python\nwhile p < k:\ns = (p + k) // 2\nif A[s] % 2 == 1:\np = s + 1\nelse:\nk = s\nreturn A[p]\n\nA = [5, 99, 3, 7, 111, 13, 4, 24, 4, 8]\nprint(pierwsza_parzysta(A, len(A))) # 4\n\n**Pascal (indeksowanie od 1 jak w CKE):**\n```pascal\nfunction PierwszaParzysta(var A: array of LongInt; n: Integer): LongInt;\nvar p, k, s: Integer;\nbegin\np := 1; k := n;\nwhile p < k do\nbegin\ns := (p + k) div 2;\nif A[s] mod 2 = 1 then\np := s + 1\nelse\nk := s;\nend;\nPierwszaParzysta := A[p];\nend;\n\n**C++:**\n```cpp\nint pierwszaParzysta(int A[], int n) {\nint p = 1, k = n;\nwhile (p < k) {\nint s = (p + k) / 2;\nif (A[s] % 2 == 1) p = s + 1;\nelse k = s;\n}\nreturn A[p];\n}\n\n**Weryfikacja na przykładzie:** A = [5,99,3,7,111,13,4,24,4,8], n=10.\n- p=1, k=10 → s=5, A[5]=111 nieparzysta → p=6.\n- p=6, k=10 → s=8, A[8]=24 parzysta → k=8.\n- p=6, k=8 → s=7, A[7]=4 parzysta → k=7.\n- p=6, k=7 → s=6, A[6]=13 nieparzysta → p=7.\n- p=7, k=7 → pętla kończy. w = A[7] = 4 ✓\n\n## Sposób 2 - wyszukiwanie liniowe O(n) [max 3 pkt]\n\nNajprostsza wersja - przeglądamy tablicę od lewej, zwracamy pierwszy element parzysty:\n\ndla i od 1 do n wykonuj\njeżeli A[i] mod 2 = 0\nw ← A[i]\nzakończ\n\n**Python:**\n```python\ndef liniowo(A):\nfor x in A:\nif x % 2 == 0:\nreturn x\n\nDziała poprawnie, ale klucz CKE nagradza maksymalnie 3 pkt zamiast 5 - uczyć się więc rozwiązania binarnego.\n\n## Reference informatyczny - wyszukiwanie binarne\n\n> Reference - Binary Search w wariancie \"znajdź pierwsze wystąpienie\":\n> - Klasyczne wyszukiwanie binarne szuka **dokładnej wartości** - tutaj szukamy **granicy** (pierwszy element spełniający warunek).\n> - Niezmiennik pętli: w przedziale `[p, k]` znajduje się szukana wartość.\n> - WAŻNE: gdy `A[s]` spełnia warunek (parzyste), ustawiamy `k = s` (NIE `s-1`!), bo `s` może być odpowiedzią.\n> - Złożoność: **O(log n)** - w każdej iteracji przedział kurczy się dwukrotnie.\n> - Wymagania: monotoniczność warunku (od pewnego momentu wszystkie elementy spełniają warunek).\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 1.1, max 5 pkt):\n> - **5 pkt** - algorytm o złożoności lepszej niż liniowa (binarka):\n> - 1 pkt - prawidłowy warunek pętli (`p < k`)\n> - 1 pkt - prawidłowe wyznaczenie podziału ciągu (s = (p+k) div 2)\n> - 1 pkt - prawidłowe wyznaczenie początku podciągu (p ← s+1)\n> - 1 pkt - prawidłowe wyznaczenie końca podciągu (k ← s)\n> - 1 pkt - prawidłowe wyznaczenie pierwszego parzystego (w ← A[p])\n> - **3 pkt** - algorytm liniowy:\n> - 1 pkt - prawidłowy przebieg pętli\n> - 1 pkt - sprawdzenie warunku parzystości\n> - 1 pkt - wyznaczenie pierwszego parzystego\n> - **0 pkt** - błędna lub brak odpowiedzi\n\n## Typowe pułapki\n\n- **`k ← s-1` zamiast `k ← s`** - gubimy kandydata; pętla może minąć poprawny indeks.\n- **`p ← s` zamiast `p ← s+1`** - pętla nie kończy się gdy A[s] nieparzysta i p == s.\n- **Warunek `p ≤ k`** zamiast `p < k` - niepotrzebna dodatkowa iteracja, ryzyko out-of-bounds.\n- **Off-by-one indeksowanie** - CKE używa od 1, Python/C++ od 0.\n- **Test parzystości** `A[s] mod 2 = 0` vs `A[s] mod 2 = 1` - łatwo pomylić kierunek.\n- **Brak założenia, że co najmniej jedna parzysta liczba istnieje** - algorytm tego nie sprawdza, ale w treści mamy gwarancję (Jaś zapisał co najmniej jedną liczbę).\n\n## Złożoność obliczeniowa\n\n- **Czas: O(log n)** - w każdej iteracji przedział `[p, k]` kurczy się o połowę.\n- **Pamięć: O(1)** - kilka zmiennych pomocniczych (p, k, s).\n- Dla porównania: rozwiązanie liniowe = O(n) (max 3 pkt w CKE).","image":"img/informatyka-2019-maj-matura-rozszerzona/zad-1.1.webp","solution_image":null,"topics":null,"page_from":2,"source":"ocr","answer_source":null,"answer_text_source":"ocr","solution_source":"maturazai","text_source":"ocr","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/1.2","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"1.2","points":1,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Zadanie 1.2. (0-1)\nPodaj, jaką złożoność czasową - kwadratową, liniową, logarytmiczną lub inną (napisz jaką) -\nma Twój algorytm.\nWypełnia\negzaminator\nNr zadania\n1.1.\n1.2.\nMaks. liczba pkt.\n5\n1\nUzyskana liczba pkt.\nMIN_1R","answer":null,"answer_text":"Zadanie 1.2. (0-1)\nWymagania ogólne\nWymagania szczegółowe\nIII. Rozwiązywanie problemów\ni podejmowanie decyzji […]\nz zastosowaniem podejścia algorytmicznego.\n5. Rozwiązywanie problemów\ni podejmowanie decyzji […], stosowanie\npodejścia algorytmicznego.\nZdający:\n4) dobiera efektywny algorytm do\nrozwiązania sytuacji problemowej i zapisuje\ngo w wybranej notacji;\n5) posługuje się podstawowymi technikami\nalgorytmicznymi;\n16) opisuje własności algorytmów na\npodstawie ich analizy;\n17) ocenia zgodność algorytmu ze\nspecyfikacją problemu;\n18) oblicza liczbę operacji wykonywanych\nprzez algorytm;\n20) bada efektywność komputerowych\nrozwiązań problemów.\nSchemat punktowania\n1 p. - za poprawną odpowiedź.\n0 p. - za podanie odpowiedzi błędnej albo brak odpowiedzi.\nPoprawna odpowiedź\nNp. dla wyszukiwania binarnego: log(n) lub logarytmiczna, dla wyszukiwania liniowego -\nzłożoność liniowa.","solution":"## Poprawna odpowiedź\n\n**Złożoność czasowa: logarytmiczna - O(log n)**\n\n(odpowiedź zgodna z algorytmem z zadania 1.1 - wyszukiwanie binarne)\n\n## Sposób 1 - analiza pętli wyszukiwania binarnego\n\nKluczowe pytanie: **ile razy wykonuje się pętla `dopóki p < k`?**\n\n- W każdej iteracji środek `s = (p+k) div 2` dzieli przedział `[p, k]` na dwie połowy.\n- Wybierając jedną z połówek (w zależności od warunku A[s] mod 2), długość przedziału kurczy się **co najmniej dwukrotnie** w każdej iteracji.\n\n**Formalnie:** jeśli na początku przedział ma długość n, to po k iteracjach ma długość co najwyżej n/2^k. Pętla kończy się gdy długość = 1, czyli n/2^k ≤ 1, skąd k ≥ log₂(n).\n\n**Liczba iteracji = ⌈log₂(n)⌉ = O(log n).**\n\n## Sposób 2 - alternatywne odpowiedzi w zależności od rozwiązania\n\n- Jeśli w zadaniu 1.1 napisałeś **wyszukiwanie liniowe** (`for i := 1 to n do `) → złożoność **liniowa O(n)** (i tylko 3 pkt w 1.1).\n- Jeśli wyszukiwanie binarne → **logarytmiczna O(log n)** (5 pkt w 1.1).\n- Inne nietypowe rozwiązania:\n- skok co `sqrt(n)` (jump search) → O(√n).\n- rekurencyjne dzielenie połowiczne → O(log n) (równoważne binary search).\n\n## Reference informatyczny - klasy złożoności\n\n> Reference - Złożoność asymptotyczna:\n> - **O(1)** - stała (np. dostęp do elementu tablicy).\n> - **O(log n)** - logarytmiczna (binarka, wysokość zbalansowanego BST).\n> - **O(n)** - liniowa (przegląd tablicy, sumowanie).\n> - **O(n log n)** - quasi-liniowa (mergesort, heapsort, quicksort średni).\n> - **O(n²)** - kwadratowa (bubble, insertion, selection sort).\n> - **O(2ⁿ)** - wykładnicza (rekurencyjny Fibonacci bez memoizacji).\n>\n> Reguły uproszczeń:\n> - Stałe się pomija: `5n + 100` → `O(n)`.\n> - Suma → bierzemy największy człon: `O(n²) + O(n)` → `O(n²)`.\n> - Iloczyn pętli zagnieżdżonych → mnoży się: `O(n)·O(log n)` → `O(n log n)`.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 1.2, max 1 pkt):\n> - **1 pkt** - poprawna odpowiedź zgodna z algorytmem z 1.1\n> - **0 pkt** - błędna lub brak\n\n**Akceptowane:** `O(log n)`, `logarytmiczna`, `log(n)`, `log₂(n)` - wszystkie równoważne.\n**Dla rozwiązania liniowego z 1.1:** `O(n)`, `liniowa`.\n\n## Typowe pułapki\n\n- **Pomylenie z poziomem pętli** - jedna pętla nie oznacza automatycznie O(n). Trzeba przeanalizować, **o ile** kurczy się przestrzeń w każdej iteracji.\n- **Niezgodność odpowiedzi z algorytmem 1.1** - jeśli w 1.1 napisałeś binarkę, ale w 1.2 piszesz \"liniowa\" - zero punktów.\n- **Mylenie log₂(n) z log₁₀(n)** - w informatyce logarytm domyślnie o podstawie 2 (lub e - nie ma znaczenia dla notacji O).\n- **Pisanie tylko `O(log)` bez `n`** - to formalnie niepoprawne.\n\n## Złożoność obliczeniowa\n\nAlgorytm wyszukiwania binarnego:\n- **Czas: O(log n)** - pętla wykonuje co najwyżej ⌈log₂ n⌉ iteracji, każda w czasie O(1).\n- **Pamięć: O(1)** - stała liczba zmiennych pomocniczych.","image":"img/informatyka-2019-maj-matura-rozszerzona/zad-1.2.webp","solution_image":null,"topics":null,"page_from":3,"source":"ocr","answer_source":null,"answer_text_source":"ocr","solution_source":"maturazai","text_source":"ocr","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/2","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"2","points":null,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Zadanie 2. Analiza algorytmu\nPrzeanalizuj podaną funkcję pisz.\nSpecyfikacja:\nDane:\ns - napis\nn - liczba całkowita dodatnia, nie mniejsza niż długość napisu s\nk - liczba całkowita z zakresu [2 10]\nfunkcja pisz(s,n,k)\njeżeli dł(s) = n\nwypisz s\nw przeciwnym razie\ndla i=0,1 … k-1 wykonuj\npisz(s + napis(i), n, k)\nUwaga:\ndł(x)\n- daje w wyniku długość napisu x\ns1 + s2\n- daje w wyniku złączenie napisów s1 i s2\nnapis(p)\n- daje w wyniku napis będący zapisem dziesiętnym liczby całkowitej p","answer":null,"answer_text":"102","solution":null,"image":"img/informatyka-2019-maj-matura-rozszerzona/zad-2.webp","solution_image":null,"topics":null,"page_from":4,"source":"ocr","answer_source":null,"answer_text_source":"ocr","solution_source":null,"text_source":"ocr","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/2.1","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"2.1","points":2,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Zadanie 2.1. (0-2)\na) Uzupełnij miejsca oznaczone kropkami w drzewie wywołań funkcji pisz otrzymanym\nw wyniku wywołania pisz(\"\",2,2).\nb) W kwadratowych polach, przy węzłach drzewa, podaj odpowiednią kolejność wywołań\nfunkcji pisz, tzn. przy pierwszym wywołaniu - 1, przy kolejnym - 2 itd.\npisz(\"\",2,2)\npisz(\"0\",2,2)\npisz(\"1\",2,2)\npisz(\"00\",2,2)\npisz(\"01\",2,2)\n1\nMIN_1R","answer":null,"answer_text":"Zadanie 2.1. (0-2)\nWymagania ogólne\nWymagania szczegółowe\nIII. Rozwiązywanie problemów\ni podejmowanie decyzji […]\nz zastosowaniem podejścia algorytmicznego.\n5. Rozwiązywanie problemów\ni podejmowanie decyzji […], stosowanie\npodejścia algorytmicznego.\nZdający:\n5) posługuje się podstawowymi technikami\nalgorytmicznymi;\n9) stosuje rekurencję w prostych sytuacjach\nproblemowych;\n11) opisuje podstawowe algorytmy\ni stosuje:[…]\nd) algorytmy na tekstach […]\n16) opisuje własności algorytmów na\npodstawie ich analizy;\n17) ocenia zgodność algorytmu ze\nspecyfikacją problemu;\n18) oblicza liczbę operacji wykonywanych\nprzez algorytm.\nSchemat punktowania\n2 p. - za poprawną odpowiedź, w tym:\n1 p. - poprawne uzupełnienie drzewka wywołań funkcji pisz,\n1 p. - prawidłową kolejność wywołań.\n0 p. - za podanie odpowiedzi błędnej albo brak odpowiedzi.\nPoprawna odpowiedź","solution":"## Poprawna odpowiedź\n\n**a) Brakujące węzły:** `pisz(\"10\", 2, 2)` i `pisz(\"11\", 2, 2)`.\n\n**b) Kolejność wywołań:**\n\n| Numer | Wywołanie |\n| 1 | pisz(\"\", 2, 2) |\n| 2 | pisz(\"0\", 2, 2) |\n| 3 | pisz(\"00\", 2, 2) |\n| 4 | pisz(\"01\", 2, 2) |\n| 5 | pisz(\"1\", 2, 2) |\n| 6 | pisz(\"10\", 2, 2) |\n| 7 | pisz(\"11\", 2, 2) |\n\n**Drzewo z numeracją (pre-order DFS):**\n\n[1] pisz(\"\", 2, 2)\n[2] pisz(\"0\", 2, 2) [5] pisz(\"1\", 2, 2)\n[3] pisz(\"00\") [4] pisz(\"01\") [6] pisz(\"10\") [7] pisz(\"11\")\n\n## Sposób 1 - symulacja rekurencji krok po kroku\n\nFunkcja `pisz(s, n, k)`:\n- jeśli `dł(s) = n` → wypisz s (warunek bazowy);\n- inaczej → dla i = 0 k-1 wywołaj `pisz(s + napis(i), n, k)`.\n\nDla `pisz(\"\", 2, 2)` (n=2, k=2):\n\n**[1] pisz(\"\", 2, 2):** dł(\"\")=0 ≠ 2 → pętla `i=0,1`:\n- i=0: wywołaj **[2] pisz(\"0\", 2, 2)**:\n- dł(\"0\")=1 ≠ 2 → pętla i=0,1:\n- i=0: **[3] pisz(\"00\", 2, 2)** → dł(\"00\")=2 → **wypisz \"00\"**.\n- i=1: **[4] pisz(\"01\", 2, 2)** → dł(\"01\")=2 → **wypisz \"01\"**.\n- i=1: wywołaj **[5] pisz(\"1\", 2, 2)**:\n- dł(\"1\")=1 ≠ 2 → pętla i=0,1:\n- i=0: **[6] pisz(\"10\", 2, 2)** → dł(\"10\")=2 → **wypisz \"10\"**.\n- i=1: **[7] pisz(\"11\", 2, 2)** → dł(\"11\")=2 → **wypisz \"11\"**.\n\n**Wypisany ciąg: 00, 01, 10, 11** (wszystkie binarne liczby 2-bitowe!).\n\n## Sposób 2 - interpretacja jako pre-order DFS po drzewie pełnym\n\nFunkcja `pisz` buduje **pełne drzewo k-arne** głębokości n. Liście to wszystkie napisy długości n nad alfabetem {0, 1, , k-1}, a wewnętrzne węzły to wszystkie krótsze prefiksy.\n\nKolejność wywołań to **pre-order traversal** (NLR): najpierw węzeł aktualny (wywołanie funkcji), potem rekurencyjnie poddrzewa od i=0 do i=k-1 (lewe do prawego).\n\n**Implementacja Python (do weryfikacji):**\n```python\nlicznik = [0]\nkolejnosc = []\n\ndef pisz(s, n, k):\nlicznik[0] += 1\nkolejnosc.append((licznik[0], s))\nif len(s) == n:\nprint(s)\nreturn\nfor i in range(k):\npisz(s + str(i), n, k)\n\npisz(\"\", 2, 2)\nfor nr, s in kolejnosc:\nprint(nr, repr(s))\n# 1 '' 2 '0' 3 '00' 4 '01' 5 '1' 6 '10' 7 '11'\n\n## Reference informatyczny - pre-order DFS\n\n> Reference - Drzewo wywołań rekurencji:\n> - Każde wywołanie funkcji = węzeł drzewa. Wywołania zagnieżdżone = krawędzie.\n> - Kolejność wywołań = **pre-order DFS** (NLR): najpierw węzeł, potem rekurencyjnie poddrzewa.\n> - Liczba liści = liczba kombinacji ciągu długości n nad alfabetem k-elementowym = **k^n**.\n> - Łączna liczba węzłów (wywołań) = 1 + k + k² + + k^n = **(k^(n+1) - 1) / (k - 1)**.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 2.1, max 2 pkt):\n> - **2 pkt** - poprawna odpowiedź, w tym:\n> - 1 pkt - poprawne uzupełnienie drzewa (pisz(\"10\") i pisz(\"11\"))\n> - 1 pkt - prawidłowa kolejność wywołań (1-7)\n> - **0 pkt** - błędna lub brak\n\n## Typowe pułapki\n\n- **Numerowanie tylko liści** zamiast wszystkich węzłów - kolejność powinna obejmować WSZYSTKIE wywołania.\n- **Pomylenie pre-order z post-order** - w post-order: 3, 4, 2, 6, 7, 5, 1 (najpierw liście, na końcu korzeń).\n- **Mylenie kolejności i=0,1** - najpierw idzie i=0 (lewa), potem i=1 (prawa).\n- **Brakujące dopisanie cyfry**: pisz(\"\") + i=1 → pisz(\"1\"), NIE pisz(\"01\").\n\n## Złożoność obliczeniowa\n\n- Liczba wywołań dla `pisz(\"\", n, k)`: **(k^(n+1) - 1) / (k - 1)**.\n- Dla pisz(\"\", 2, 2): (2³ - 1)/(2 - 1) = 7 ✓.\n- Czas pojedynczego wywołania (bez rekurencji): O(dł(s)) na konkatenację - łącznie O(n · k^n).\n- Pamięć stosu rekurencji: O(n) (głębokość drzewa).","image":"img/informatyka-2019-maj-matura-rozszerzona/zad-2.1.webp","solution_image":null,"topics":null,"page_from":4,"source":"ocr","answer_source":null,"answer_text_source":"ocr","solution_source":"maturazai","text_source":"ocr","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/2.2","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"2.2","points":2,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Zadanie 2.2. (0-2)\nUzupełnij poniższą tabelę - przeanalizuj podane w niej wywołania funkcji pisz. Podaj napisy\nwypisywane w wyniku wywołania funkcji pisz z zadanymi parametrami oraz łączną liczbę\nwywołań tej funkcji.\nPierwsze wywołanie\nfunkcji pisz\nNapisy wypisane w wyniku wywołania\nfunkcji pisz\nŁączna liczba\nwywołań funkcji\npisz\npisz(\"\", 3, 2)\npisz(\"\", 2, 3)","answer":null,"answer_text":"Zadanie 2.2. (0-2)\nWymagania ogólne\nWymagania szczegółowe\nIII. Rozwiązywanie problemów\ni podejmowanie decyzji […]\nz zastosowaniem podejścia algorytmicznego.\n5. Rozwiązywanie problemów\ni podejmowanie decyzji […], stosowanie\npodejścia algorytmicznego.\nZdający:\n5) posługuje się podstawowymi technikami\nalgorytmicznymi;\n9) stosuje rekurencję w prostych sytuacjach\nproblemowych;\n11) opisuje podstawowe algorytmy\ni stosuje:\na) algorytmy na tekstach, […]\n16) opisuje własności algorytmów na\npodstawie ich analizy;\n17) ocenia zgodność algorytmu ze\nspecyfikacją problemu;\n18) oblicza liczbę operacji wykonywanych\nprzez algorytm.\nSchemat punktowania\n2 p. - za poprawną odpowiedź, w tym:\n1 p. - za każde poprawnie uzupełnione dwa pola tabeli.\nUwaga: teksty wypisane przez funkcję mogą być zapisane w jednym wierszu lub jeden pod\ndrugim - nie zmienia to oceny.\n0 p. - za podanie odpowiedzi błędnej albo brak odpowiedzi.\nPoprawna odpowiedź\nwywołanie\nfunkcji\ntekst wypisany przez\nfunkcję pisz()\nliczba wywołań\nfunkcji pisz()\npisz(\"\", 3, 2)\n000\n001\n010\n011\n100\n101\n110\n111\n15 (1+2+4+8)\npisz(\"\", 2, 3)\n00\n01\n02\n10\n11\n12\n20\n21\n22\n13 (1+3+9)","solution":"## Poprawna odpowiedź\n\n| Wywołanie | Wypisane napisy | Łączna liczba wywołań |\n| pisz(\"\", 3, 2) | **000, 001, 010, 011, 100, 101, 110, 111** | **15** |\n| pisz(\"\", 2, 3) | **00, 01, 02, 10, 11, 12, 20, 21, 22** | **13** |\n\n## Sposób 1 - analiza pisz(\"\", 3, 2)\n\n**Co wypisze?** Funkcja generuje wszystkie napisy długości n=3 nad alfabetem {0, 1} (bo k=2). Liczba liści = 2³ = 8 napisów.\n\nW porządku pre-order (najpierw i=0, potem i=1):\n\"\" → \"0\" → \"00\" → \"000\" (wypisz)\n\"001\" (wypisz)\n\"01\" → \"010\" (wypisz)\n\"011\" (wypisz)\n\"1\" → \"10\" → \"100\" (wypisz)\n\"101\" (wypisz)\n\"11\" → \"110\" (wypisz)\n\"111\" (wypisz)\n\nWypisane: **000, 001, 010, 011, 100, 101, 110, 111** (binarne liczby 0-7).\n\n**Liczba wywołań - liczenie po poziomach:**\n- poziom 0 (\"\"): 1 wywołanie\n- poziom 1 (\"0\", \"1\"): 2 wywołania\n- poziom 2 (\"00\", \"01\", \"10\", \"11\"): 4 wywołania\n- poziom 3 (liście, 8 napisów): 8 wywołań\n\nSuma: **1 + 2 + 4 + 8 = 15** wywołań.\n\n## Sposób 2 - analiza pisz(\"\", 2, 3)\n\nFunkcja generuje wszystkie napisy długości n=2 nad alfabetem {0, 1, 2} (k=3). Liczba liści = 3² = 9.\n\nW porządku pre-order (i=0, potem 1, potem 2):\n\"\" → \"0\" → \"00\" (wypisz)\n\"01\" (wypisz)\n\"02\" (wypisz)\n\"1\" → \"10\" (wypisz)\n\"11\" (wypisz)\n\"12\" (wypisz)\n\"2\" → \"20\" (wypisz)\n\"21\" (wypisz)\n\"22\" (wypisz)\n\nWypisane: **00, 01, 02, 10, 11, 12, 20, 21, 22**.\n\n**Liczba wywołań po poziomach:**\n- poziom 0: 1 wywołanie\n- poziom 1: 3 wywołania (\"0\", \"1\", \"2\")\n- poziom 2 (liście): 9 wywołań\n\nSuma: **1 + 3 + 9 = 13**.\n\n## Sposób 3 - implementacja Python (weryfikacja)\n\n```python\ndef pisz(s, n, k, wynik, licznik):\nlicznik[0] += 1\nif len(s) == n:\nwynik.append(s)\nreturn\nfor i in range(k):\npisz(s + str(i), n, k, wynik, licznik)\n\nlicznik = [0]; wynik = []\npisz(\"\", 3, 2, wynik, licznik)\nprint(wynik)\n# ['000', '001', '010', '011', '100', '101', '110', '111']\nprint(\"liczba wywołań:\", licznik[0]) # 15\n\nlicznik = [0]; wynik = []\npisz(\"\", 2, 3, wynik, licznik)\nprint(wynik)\n# ['00', '01', '02', '10', '11', '12', '20', '21', '22']\nprint(\"liczba wywołań:\", licznik[0]) # 13\n\n## Reference informatyczny - wzór na liczbę wywołań\n\n> Reference - Sumowanie szeregu geometrycznego:\n> - Liczba wywołań pisz(\"\", n, k) = 1 + k + k² + + kⁿ.\n> - To suma szeregu geometrycznego: **(kⁿ⁺¹ - 1) / (k - 1)** dla k ≠ 1.\n> - Dla n=3, k=2: (2⁴ - 1)/(2 - 1) = 15 ✓.\n> - Dla n=2, k=3: (3³ - 1)/(3 - 1) = 26/2 = 13 ✓.\n> - Liczba liści (wypisanych napisów) = **kⁿ**.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 2.2, max 2 pkt):\n> - **2 pkt** - wszystkie 4 pola tabeli poprawne\n> - **1 pkt** - za każde 2 poprawnie uzupełnione pola\n> - **0 pkt** - błędna lub brak\n>\n> Uwaga: teksty wypisane mogą być w jednym wierszu lub jeden pod drugim.\n\n## Typowe pułapki\n\n- **Pomylenie kolejności wypisywania** - pre-order daje wzrost \"leksykograficzny\": 000 < 001 < 010 < 011\n- **Liczenie tylko liści (8 lub 9) zamiast wszystkich wywołań** - wynikają z tego błędne 8 (zamiast 15) lub 9 (zamiast 13).\n- **Liczenie tylko węzłów wewnętrznych** - pomijanie liści.\n- **Pomylenie kolejności n i k**: pisz(\"\", 3, 2) ≠ pisz(\"\", 2, 3).\n- **Brak wypisania niektórych ścieżek** - łatwo zgubić jakąś gałąź.\n\n## Złożoność obliczeniowa\n\n- Czas: **O((kⁿ⁺¹ - 1)/(k - 1))** = **Θ(kⁿ)** dla k > 1.\n- Pamięć stosu: O(n).\n- Dla pisz(\"\", 3, 2): 15 wywołań, 8 wypisań.\n- Dla pisz(\"\", 2, 3): 13 wywołań, 9 wypisań.","image":"img/informatyka-2019-maj-matura-rozszerzona/zad-2.2.webp","solution_image":null,"topics":null,"page_from":5,"source":"ocr","answer_source":null,"answer_text_source":"ocr","solution_source":"maturazai","text_source":"ocr","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/2.3","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"2.3","points":2,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Zadanie 2.3. (0-2)\nPodaj wzór na łączną liczbę wywołań funkcji pisz w wyniku wywołania pisz(\"\", n, k).\nWypełnia\negzaminator\nNr zadania\n2.1.\n2.2.\n2.3.\nMaks. liczba pkt.\n2\n2\n2\nUzyskana liczba pkt.\nMIN_1R","answer":null,"answer_text":"Zadanie 2.3. (0-2)\nWymagania ogólne\nWymagania szczegółowe\nIII. Rozwiązywanie problemów\ni podejmowanie decyzji […]\nz zastosowaniem podejścia algorytmicznego.\n5. Rozwiązywanie problemów\ni podejmowanie decyzji […], stosowanie\npodejścia algorytmicznego.\nZdający:\n5) posługuje się podstawowymi technikami\nalgorytmicznymi;\n9) stosuje rekurencję w prostych sytuacjach\nproblemowych;\n16) opisuje własności algorytmów na\npodstawie ich analizy;\n17) ocenia zgodność algorytmu ze\nspecyfikacją problemu;\n18) oblicza liczbę operacji wykonywanych\nprzez algorytm.\nSchemat punktowania\n2 p. - za poprawną odpowiedź,\n1 p. - w przypadku podania w odpowiedzi liczby mniejszej o 1 lub gdy ostatni element szeregu\nw odpowiedzi ma indeks n-1 zamiast n (np. 1+k+k2+…+kn-1 zamiast 1+k+k2+…+kn),\n0 p. - za podanie odpowiedzi błędnej albo brak odpowiedzi.\nUwaga: odpowiedź może być zapisana także w postaci sumy (ze znakiem ∑ ).\nPoprawna odpowiedź\n(kn+1 - 1)/(k - 1) lub (1 - kn+1)/(1- k) lub 1 + k + k2 + … + kn","solution":"## Poprawna odpowiedź\n\n**Wzór na łączną liczbę wywołań:**\n\n$$\nT(n, k) = 1 + k + k^2 + k^3 + \\ldots + k^n = \\frac{k^{n+1} - 1}{k - 1}\n$$\n\n(dla k = 1 wzór ten się degeneruje; wtedy T(n, 1) = n + 1.)\n\nAlternatywne równoważne zapisy:\n- `(k^(n+1) - 1) / (k - 1)`\n- `(1 - k^(n+1)) / (1 - k)`\n- `1 + k + k^2 + + k^n`\n- `Σ k^i dla i = 0 n`\n\n## Sposób 1 - analiza poziomami drzewa\n\nFunkcja `pisz(\"\", n, k)` buduje **pełne drzewo k-arne głębokości n**. Każde wywołanie na poziomie i (gdzie i = 0, 1, , n) odpowiada jednemu napisowi długości i.\n\n**Liczba wywołań na poziomie i = k^i** (liczba ciągów długości i nad alfabetem k-elementowym):\n\n| Poziom | Liczba wywołań |\n| 0 (korzeń) | k⁰ = 1 |\n| 1 | k¹ = k |\n| 2 | k² |\n| n (liście) | kⁿ |\n\n**Suma wszystkich poziomów:**\n\n$$T(n,k) = \\sum_{i=0}^{n} k^i = 1 + k + k^2 + \\ldots + k^n$$\n\n## Sposób 2 - wzór sumy szeregu geometrycznego\n\nZastosujmy wzór na sumę szeregu geometrycznego z pierwszym wyrazem a=1 i ilorazem q=k:\n\n$$S_n = a \\cdot \\frac{q^{n+1} - 1}{q - 1} = \\frac{k^{n+1} - 1}{k - 1}, \\quad k \\ne 1$$\n\n**Weryfikacja na danych z zadania 2.2:**\n- pisz(\"\", 3, 2): (2⁴ - 1)/(2 - 1) = 15 ✓\n- pisz(\"\", 2, 3): (3³ - 1)/(3 - 1) = 26/2 = 13 ✓\n- pisz(\"\", 2, 2): (2³ - 1)/(2 - 1) = 7 ✓ (z zad. 2.1)\n\n## Sposób 3 - wzór rekurencyjny i jego rozwinięcie\n\nNiech T(n, k) = liczba wywołań pisz(s, n, k), gdzie dł(s) = 0 (lub równoważnie pisz(s, n-dł(s), k) dla dowolnego s).\n\n**Rekurencja:**\n- Bazowo: T(0, k) = 1 (tylko jedno wywołanie - od razu wypisuje).\n- Ogólnie: T(n, k) = 1 (samo wywołanie) + k razy poddrzewa: T(n, k) = 1 + k · T(n-1, k).\n\nRozwiązanie:\n- T(0, k) = 1\n- T(1, k) = 1 + k\n- T(2, k) = 1 + k(1 + k) = 1 + k + k²\n- T(n, k) = 1 + k + k² + + kⁿ ✓\n\n## Reference informatyczny - suma szeregu geometrycznego\n\n> Reference - Szereg geometryczny:\n> - Suma: 1 + q + q² + + qⁿ = **(qⁿ⁺¹ - 1) / (q - 1)** dla q ≠ 1.\n> - Dla q = 1: suma = n + 1.\n> - Liczba węzłów pełnego drzewa k-arnego głębokości n: **(kⁿ⁺¹ - 1) / (k - 1)**.\n> - Liczba liści: **kⁿ**.\n> - Liczba węzłów wewnętrznych: T(n,k) - kⁿ = (kⁿ - 1) / (k - 1).\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 2.3, max 2 pkt):\n> - **2 pkt** - pełna poprawna odpowiedź (dowolna z równoważnych form)\n> - **1 pkt** - liczba mniejsza o 1 lub indeks szeregu n-1 zamiast n (np. 1+k+ +k^(n-1) zamiast 1+k+ +kⁿ)\n> - **0 pkt** - błędna lub brak\n>\n> Uwaga: odpowiedź może być zapisana także w postaci sumy ze znakiem Σ.\n\n## Typowe pułapki\n\n- **Liczenie tylko liści (kⁿ) zamiast wszystkich wywołań** - typowy błąd: \"funkcja wypisuje kⁿ napisów więc tyle jest wywołań\".\n- **Pomylenie n+1 i n w wykładniku**: 1+k+ +k^(n-1) (suma do n-1) zamiast do kⁿ.\n- **Dzielenie przez (k-1) i zapominanie o przypadku k=1** (chociaż w treści mamy k ∈ [2 10], więc k ≥ 2).\n- **Mylenie głębokości drzewa**: drzewo ma głębokość n, ale jego poziomy są ponumerowane 0, 1, , n - czyli n+1 poziomów.\n\n## Złożoność obliczeniowa\n\n- T(n, k) = **Θ(kⁿ)** - dominujący człon w sumie geometrycznej.\n- Dla k=2: T(n,2) = 2ⁿ⁺¹ - 1 - wykładnicza w n.\n- Pamięć stosu rekurencji: O(n).","image":"img/informatyka-2019-maj-matura-rozszerzona/zad-2.3.webp","solution_image":null,"topics":null,"page_from":5,"source":"ocr","answer_source":null,"answer_text_source":"ocr","solution_source":"maturazai","text_source":"ocr","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/3","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"3","points":null,"ptype":"true_false","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Zadanie 3. Test\nOceń prawdziwość podanych zdań. Zaznacz P, jeśli zdanie jest prawdziwe, albo F - jeśli jest\nfałszywe.\nW każdym zadaniu punkt uzyskasz tylko za komplet poprawnych odpowiedzi.","answer":null,"answer_text":"102","solution":null,"image":"img/informatyka-2019-maj-matura-rozszerzona/zad-3.webp","solution_image":null,"topics":null,"page_from":6,"source":"ocr","answer_source":null,"answer_text_source":"ocr","solution_source":null,"text_source":"ocr","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/3.1","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"3.1","points":1,"ptype":"true_false","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Zadanie 3.1. (0-1)\nDana jest tabela PRACOWNICY.\nNr_P\nNazwisko\nImię\nStanowisko\nNr_działu\n736\nSmitko\nAlan\nurzędnik\n20\n7499\nNowak\nKazimierz\nsprzedawca\n30\n7521\nWięcek\nMariusz\nsprzedawca\n30\n7566\nJonas\nKamil\nkierownik\n20\n7654\nMartin\nLeon\nsprzedawca\n30\n7698\nBracki\nBartosz\nkierownik\n30\n7782\nCelerek\nAgnieszka\nkierownik\n10\n7788\nSkotnik\nNatalia\nanalityk\n20\n7839\nKing\nMirosława\nprezes\n10\n1.\nWynikiem zapytania\nSELECT COUNT(Stanowisko)\nFROM PRACOWNICY;\njest\nStanowisko 5\nP\nF\n2.\nWynikiem zapytania\nSELECT COUNT(Stanowisko)\nFROM PRACOWNICY\nWHERE Stanowisko <> \"kierownik\";\njest\n6\nP\nF\n3.\nWynikiem zapytania\nSELECT Stanowisko, COUNT(*)\nFROM PRACOWNICY\nGROUP BY Stanowisko;\njest\nurzędnik 1\nsprzedawca 3\nkierownik 3\nanalityk 1\nprezes 1\nP\nF\n4.\nWynikiem zapytania\nSELECT COUNT(Stanowisko)\nFROM PRACOWNICY\nWHERE Stanowisko LIKE \"*nik\";\njest\n2\nP\nF\nMIN_1R","answer":"F","answer_text":"Zadanie 3.1. (0-1)\nWymagania ogólne\nWymagania szczegółowe\nII. Wyszukiwanie, gromadzenie\ni przetwarzanie informacji z różnych źródeł;\nopracowywanie za pomocą komputera:\nrysunków, tekstów, danych liczbowych,\nmotywów, animacji, prezentacji\nmultimedialnych.\n2. Wyszukiwanie, gromadzenie,\nselekcjonowanie, przetwarzanie\ni wykorzystywanie informacji,\nwspółtworzenie zasobów w sieci,\nkorzystanie z różnych źródeł i sposobów\nzdobywania informacji.\nZdający:\n2) stosuje metody wyszukiwania\ni przetwarzania informacji w relacyjnej\nbazie danych (język SQL).\nSchemat punktowania\n1 p. - za wskazanie czterech poprawnych odpowiedzi.\n0 p. - za odpowiedź niepełną lub błędną albo za brak odpowiedzi.\nPoprawna odpowiedź\nF, P, P, F","solution":"## Poprawna odpowiedź\n\n**F, P, P, F**\n\n## Sposób 1 - analiza każdego zapytania na tabeli PRACOWNICY\n\nTabela ma **9 wierszy**. Lista stanowisk:\n- urzędnik (1): Smitko\n- sprzedawca (3): Nowak, Więcek, Martin\n- kierownik (3): Jonas, Bracki, Celerek\n- analityk (1): Skotnik\n- prezes (1): King\n\n### Stwierdzenie 1: `SELECT COUNT(Stanowisko) FROM PRACOWNICY;` → \"Stanowisko 5\"\n\n**Analiza:**\n- `COUNT(Stanowisko)` zlicza WSZYSTKIE wiersze (z niepustym Stanowisko) - to **9**, nie 5!\n- Nazwa kolumny wyniku nie jest \"Stanowisko 5\", a sam wynik to liczba 9.\n- Wartość 5 mogłaby wynikać tylko gdyby ktoś pomylił z `COUNT(DISTINCT Stanowisko)` - wtedy wynik = 5 (bo unikalnych stanowisk jest 5).\n\n**Werdykt: FAŁSZ** ✗\n\n### Stwierdzenie 2: `SELECT COUNT(Stanowisko) FROM PRACOWNICY WHERE Stanowisko <> \"kierownik\";` → 6\n\n**Analiza:**\n- WHERE Stanowisko <> \"kierownik\" → wykluczamy 3 kierowników (Jonas, Bracki, Celerek).\n- Pozostaje: 9 - 3 = **6 wierszy**.\n- COUNT zlicza pozostałe → wynik = 6 ✓\n\n**Werdykt: PRAWDA** ✓\n\n### Stwierdzenie 3: `SELECT Stanowisko, COUNT(*) FROM PRACOWNICY GROUP BY Stanowisko;` → \"urzędnik 1, sprzedawca 3, kierownik 3, analityk 1, prezes 1\"\n\n**Analiza GROUP BY:**\n| Stanowisko | COUNT(*) |\n| urzędnik | 1 |\n| sprzedawca | 3 |\n| kierownik | 3 |\n| analityk | 1 |\n| prezes | 1 |\n\nWynik dokładnie odpowiada opisowi! (kolejność wierszy w GROUP BY bez ORDER BY jest niegwarantowana, ale wartości są poprawne)\n\n**Werdykt: PRAWDA** ✓\n\n### Stwierdzenie 4: `SELECT COUNT(Stanowisko) FROM PRACOWNICY WHERE Stanowisko LIKE \"*nik\";` → 2\n\n**Analiza wzorca LIKE:**\n- W standardowym SQL znak `%` to dowolny ciąg (a `*` to NIE jest standardowy SQL - to wildcard z Access/wzorca DOS).\n- **W SQL standardowym (MySQL, PostgreSQL):** `LIKE '*nik'` szuka dokładnie napisu \"*nik\" (z literalną gwiazdką) → 0 wyników!\n- **W Access (z * jako wildcardem):** `LIKE \"*nik\"` ≈ \"%nik\" w SQL - kończące się na \"nik\". Pasują: \"urzędnik\" (1), \"analityk\"? - NIE (kończy się \"yk\"), \"kierownik\" (3 wystąpienia). Łącznie urzędnik (1) + kierownik (3) = **4 wiersze**.\n\nW żadnej interpretacji wynik nie wynosi 2.\n\n**Werdykt: FAŁSZ** ✗\n\n## Sposób 2 - weryfikacja Pythonem\n\n```python\nimport sqlite3\nconn = sqlite3.connect(':memory:')\nc = conn.cursor()\nc.execute('''CREATE TABLE PRACOWNICY (Nr_P INT, Nazwisko TEXT, Imie TEXT, Stanowisko TEXT, Nr_dzialu INT)''')\ndane = [(736,'Smitko','Alan','urzędnik',20),\n(7499,'Nowak','Kazimierz','sprzedawca',30),\n(7521,'Więcek','Mariusz','sprzedawca',30),\n(7566,'Jonas','Kamil','kierownik',20),\n(7654,'Martin','Leon','sprzedawca',30),\n(7698,'Bracki','Bartosz','kierownik',30),\n(7782,'Celerek','Agnieszka','kierownik',10),\n(7788,'Skotnik','Natalia','analityk',20),\n(7839,'King','Mirosława','prezes',10)]\nc.executemany('INSERT INTO PRACOWNICY VALUES (?,?,?,?,?)', dane)\n\nprint(c.execute('SELECT COUNT(Stanowisko) FROM PRACOWNICY').fetchone())\n# (9,) - nie 5\nprint(c.execute('SELECT COUNT(Stanowisko) FROM PRACOWNICY WHERE Stanowisko <> \"kierownik\"').fetchone())\n# (6,)\nprint(c.execute('SELECT Stanowisko, COUNT(*) FROM PRACOWNICY GROUP BY Stanowisko').fetchall())\n# [('analityk',1), ('kierownik',3), ('prezes',1), ('sprzedawca',3), ('urzędnik',1)]\nprint(c.execute('SELECT COUNT(Stanowisko) FROM PRACOWNICY WHERE Stanowisko LIKE \"%nik\"').fetchone())\n# (4,) - przy LIKE %nik (urzędnik 1 + 3 kierownik)\n\n## Reference informatyczny - SQL: COUNT, WHERE, GROUP BY, LIKE\n\n> Reference - SQL agregacja:\n> - `COUNT(*)` - liczba wierszy (włącznie z NULL).\n> - `COUNT(kolumna)` - liczba wierszy z NIE-NULL wartością w kolumnie.\n> - `COUNT(DISTINCT kolumna)` - liczba unikalnych wartości.\n> - `GROUP BY` - grupowanie wierszy, agregaty obliczane per grupa.\n> - `WHERE` - filtr przed grupowaniem (rzęd na rzędzie).\n> - `HAVING` - filtr po grupowaniu (na agregatach).\n>\n> Reference - SQL LIKE:\n> - Standard SQL: `%` = dowolny ciąg, `_` = jeden znak.\n> - `LIKE '%nik'` - kończy się na \"nik\".\n> - `LIKE 'nik%'` - zaczyna od \"nik\".\n> - `LIKE '%nik%'` - zawiera \"nik\".\n> - W MS Access: `*` zamiast `%`. W SQLite/MySQL/Postgres `*` to literalna gwiazdka!\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 3.1, max 1 pkt):\n> - **1 pkt** - wszystkie 4 odpowiedzi poprawne (F, P, P, F)\n> - **0 pkt** - odpowiedź niepełna lub błędna albo brak\n\n## Dlaczego inne odpowiedzi błędne (analiza pułapek)\n\n| Stw. | Trafna ocena | Typowa pułapka prowadząca do błędnej |\n| 1 | F | Mylenie COUNT(kol) z COUNT(DISTINCT kol) - wynik 9 vs 5 |\n| 2 | P | - |\n| 3 | P | Pomylenie GROUP BY z ORDER BY (kolejność wierszy) |\n| 4 | F | Założenie, że `*` to wildcard SQL (jest `%`); też mylenie urzędnik vs kierownik vs analityk |\n\n## Typowe pułapki\n\n- **`COUNT(*)` vs `COUNT(kolumna)` vs `COUNT(DISTINCT kolumna)`** - różne zachowania!\n- **Wildcard `*` vs `%`** - `%` to standard SQL, `*` to Access (lub literalna gwiazdka w innych dialektach).\n- **`<>` to nie-równe** w SQL (alternatywnie `!=` w niektórych dialektach).\n- **GROUP BY bez ORDER BY** - kolejność wierszy w wyniku nie jest gwarantowana (ale wartości są).\n- **Polskie litery** w stanowiskach (ż, ć, ą) - kodowanie znaków może mieć znaczenie.\n\n## Złożoność obliczeniowa\n\n- COUNT i WHERE: O(n) - przegląd tabeli (z indeksem szybciej).\n- GROUP BY: O(n log n) (sortowanie) lub O(n) z hash-aggregate.\n- LIKE z prefiksem (`'nik%'`) może użyć indeksu B-tree → O(log n + k). Z `%` na początku (`%nik`) → pełny skan O(n).","image":"img/informatyka-2019-maj-matura-rozszerzona/zad-3.1.webp","solution_image":null,"topics":null,"page_from":6,"source":"ocr","answer_source":"maturazai","answer_text_source":"ocr","solution_source":"maturazai","text_source":"ocr","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/3.2","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"3.2","points":1,"ptype":"true_false","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Zadanie 3.2. (0-1)\nPo pomnożeniu dwóch liczb 11111102 oraz 1012 zapisanych w systemie dwójkowym\notrzymamy:\n1.\n213124\nP\nF\n2.\n10010101102\nP\nF\n3.\n11668\nP\nF\n4.\n27616\nP\nF\nMiejsce na obliczenia","answer":null,"answer_text":"Zadanie 3.2. (0-1)\nWymagania ogólne\nWymagania szczegółowe\nI. Bezpieczne posługiwanie się komputerem\ni jego oprogramowaniem, wykorzystanie\nsieci komputerowej; komunikowanie się za\npomocą komputera i technologii\ninformacyjno-komunikacyjnych.\n1. Posługiwanie się komputerem i jego\noprogramowaniem, korzystanie z sieci\nkomputerowej.\nZdający:\n1) przedstawia sposoby reprezentowania\nróżnych form informacji w komputerze:\nliczb, znaków, obrazów, animacji,\ndźwięków.\nSchemat punktowania\n1 p. - za wskazanie czterech poprawnych odpowiedzi.\n0 p. - za odpowiedź niepełną lub błędną albo za brak odpowiedzi.\nPoprawna odpowiedź\nP, F, P, P","solution":"## Poprawna odpowiedź\n\n**P, F, P, P**\n\n## Sposób 1 - obliczenie iloczynu i konwersje\n\n**Krok 1: zamień liczby binarne na dziesiętne.**\n\n`1111110₂` = 1·64 + 1·32 + 1·16 + 1·8 + 1·4 + 1·2 + 0·1 = 64+32+16+8+4+2 = **126**\n\n`101₂` = 1·4 + 0·2 + 1·1 = **5**\n\n**Krok 2: oblicz iloczyn dziesiętnie.**\n\n126 · 5 = **630**\n\n**Krok 3: konwersja 630 na różne systemy.**\n\n### Na system czwórkowy (Stwierdzenie 1: 21312₄?)\n\n630 : 4 = 157 r 2\n157 : 4 = 39 r 1\n39 : 4 = 9 r 3\n9 : 4 = 2 r 1\n2 : 4 = 0 r 2\nCzytane od dołu: **21312₄** ✓\n\n**Weryfikacja:** 2·256 + 1·64 + 3·16 + 1·4 + 2 = 512 + 64 + 48 + 4 + 2 = 630 ✓\n\n**Werdykt 1: PRAWDA** ✓\n\n### Na system binarny (Stwierdzenie 2: 1001010110₂?)\n\n630 : 2 = 315 r 0\n315 : 2 = 157 r 1\n157 : 2 = 78 r 1\n78 : 2 = 39 r 0\n39 : 2 = 19 r 1\n19 : 2 = 9 r 1\n9 : 2 = 4 r 1\n4 : 2 = 2 r 0\n2 : 2 = 1 r 0\n1 : 2 = 0 r 1\nCzytane od dołu: **1001110110₂**\n\nW stwierdzeniu jest 1001010110₂, czyli ma 0 zamiast 1 na pozycji bitu 6 (= wartości 64). Sprawdzimy: 1001010110₂ = 512 + 64 + 16 + 4 + 2 = 598 ≠ 630.\n\n**Werdykt 2: FAŁSZ** ✗\n\n### Na system ósemkowy (Stwierdzenie 3: 1166₈?)\n\n630 : 8 = 78 r 6\n78 : 8 = 9 r 6\n9 : 8 = 1 r 1\n1 : 8 = 0 r 1\nCzytane od dołu: **1166₈** ✓\n\n**Weryfikacja:** 1·512 + 1·64 + 6·8 + 6·1 = 512 + 64 + 48 + 6 = 630 ✓\n\n**Werdykt 3: PRAWDA** ✓\n\n### Na system szesnastkowy (Stwierdzenie 4: 276₁₆?)\n\n630 : 16 = 39 r 6\n39 : 16 = 2 r 7\n2 : 16 = 0 r 2\nCzytane od dołu: **276₁₆** ✓\n\n**Weryfikacja:** 2·256 + 7·16 + 6 = 512 + 112 + 6 = 630 ✓\n\n**Werdykt 4: PRAWDA** ✓\n\n## Sposób 2 - mnożenie binarne (bez konwersji na dziesiętny)\n\n1111110\n× 101\n1111110 (× 1, bit 0)\n0000000 (× 0, bit 1) - zerowy\n1111110 (× 1, bit 2, przesunięcie o 2)\n1001110110\n\nDodawanie binarne (z przeniesieniami):\n0001111110\n+ 0000000000\n+ 0111111000\n1001110110₂\n\nTo nasze prawdziwe binarne **1001110110₂**, NIE \"1001010110\" - różnica w bicie nr 6 (wartość 64).\n\n## Sposób 3 - weryfikacja Pythonem\n\n```python\nn = 0b1111110 * 0b101\nprint(n) # 630\nprint(bin(n)) # 0b1001110110\nprint(oct(n)) # 0o1166\nprint(hex(n)) # 0x276\nprint(int('21312', 4)) # 630 - czwórkowy\n\n## Reference informatyczny - konwersje między systemami liczbowymi\n\n> Reference - Konwersje:\n> - **Bin → Dec:** suma bitów·potęg 2 od najmłodszego.\n> - **Dec → Bin:** dzielenie z resztą przez 2, czyt. od dołu.\n> - **Dec → Hex:** dzielenie z resztą przez 16. Cyfry 10=A, 11=B, , 15=F.\n> - **Dec → Oct:** dzielenie z resztą przez 8.\n> - **Bin → Hex:** grupuj po 4 bity od końca: 1001110110 → 0010|0111|0110 = 2|7|6 = 276₁₆.\n> - **Bin → Oct:** grupuj po 3 bity od końca: 1|001|110|110 = 1|1|6|6 = 1166₈.\n> - **Bin ↔ Czwórkowy:** grupuj po 2 bity: 10|01|11|01|10 = 2|1|3|1|2 = 21312₄.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 3.2, max 1 pkt):\n> - **1 pkt** - wszystkie 4 odpowiedzi (P, F, P, P)\n> - **0 pkt** - błędna lub niepełna\n\n## Dlaczego inne opcje błędne - analiza\n\n| Stw. | Wartość | Wynik 1·obliczenia | Werdykt |\n| 1 | 21312₄ | 21312₄ = 2·256+64+48+4+2 = 630 ✓ | P |\n| 2 | 1001010110₂ | = 512+64+16+4+2 = **598** ≠ 630 | F |\n| 3 | 1166₈ | = 512+64+48+6 = 630 ✓ | P |\n| 4 | 276₁₆ | = 512+112+6 = 630 ✓ | P |\n\n## Typowe pułapki\n\n- **Mnożenie binarne ręczne** - łatwo zgubić bit. Bezpieczniej najpierw przeliczyć na dziesiętny.\n- **Mylenie liczby cyfr przy konwersji** - 630 to 10 cyfr binarnych, 4 cyfry czwórkowe, 4 cyfry oktalne, 3 cyfry hex.\n- **Konwersja binary↔hex grupowaniem** - grupuj od PRAWEJ strony po 4 bity (uzupełnij zerami z lewej jeśli trzeba).\n- **Sprawdzenie szybkim trickiem**: suma cyfr binarnych w 1001110110 = 6 jedynek, w 1001010110 = 5 jedynek - różne.\n\n## Złożoność obliczeniowa\n\n- Konwersja liczby N z systemu o podstawie b: O(log_b N) - liczba cyfr.\n- Mnożenie binarne dwóch liczb o m i n bitach: O(m · n) algorytmem szkolnym.","image":"img/informatyka-2019-maj-matura-rozszerzona/zad-3.2.webp","solution_image":null,"topics":null,"page_from":7,"source":"ocr","answer_source":null,"answer_text_source":"ocr","solution_source":"maturazai","text_source":"ocr","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/3.3","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"3.3","points":1,"ptype":"true_false","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Zadanie 3.3. (0-1)\n1.\nDNS to skrót od Domain Name System.\nP\nF\n2.\nDo danego adresu IP może być przypisanych wiele różnych nazw.\nP\nF\n3.\nPrzy zmianie adresu IP komputera pełniącego funkcję serwera WWW\njest konieczna zmiana nazwy domeny internetowej.\nP\nF\n4.\nSystem DNS ma jedną centralną bazę danych adresów IP i nazw.\nP\nF\nWypełnia\negzaminator\nNr zadania\n3.1.\n3.2.\n3.3.\nMaks. liczba pkt.\n1\n1\n1\nUzyskana liczba pkt.\nMIN_1R\nBRUDNOPIS (nie podlega ocenie)","answer":null,"answer_text":"Zadanie 3.3. (0-1)\nWymagania ogólne\nWymagania szczegółowe\nI. Bezpieczne posługiwanie się komputerem\ni jego oprogramowaniem, wykorzystanie\nsieci komputerowej; komunikowanie się za\npomocą komputera i technologii\ninformacyjno-komunikacyjnych.\n1. Bezpieczne posługiwanie się\nkomputerem, jego oprogramowaniem\ni korzystanie z sieci komputerowej.\nZdający:\n3) […] określa ustawienia sieciowe danego\nkomputera i jego lokalizacji w sieci, opisuje\nzasady administrowania siecią\nkomputerową w architekturze klient-\nserwer, prawidłowo posługuje się\nterminologią sieciową, korzysta z usług\nw sieci komputerowej, lokalnej i globalnej,\nzwiązanych z dostępem do informacji,\nwymianą informacji i komunikacją.\nSchemat punktowania\n1 p. - za wskazanie czterech poprawnych odpowiedzi.\n0 p. - za odpowiedź niepełną lub błędną albo za brak odpowiedzi.\nPoprawna odpowiedź\nP, P, F, F\nCzęść II\nUwaga: wszystkie wyniki muszą być odzwierciedleniem dołączonej komputerowej realizacji\nobliczeń.","solution":"## Poprawna odpowiedź\n\n**P, P, F, F**\n\n## Sposób 1 - analiza każdego stwierdzenia\n\n### Stwierdzenie 1: \"DNS to skrót od Domain Name System.\"\n\n**Werdykt: PRAWDA** ✓\n\nDNS = **D**omain **N**ame **S**ystem (system nazw domen). To system tłumaczący czytelne dla człowieka nazwy domen (np. `maturazai.pl`) na adresy IP (np. `104.21.x.x`), z których faktycznie korzysta sieć.\n\n### Stwierdzenie 2: \"Do danego adresu IP może być przypisanych wiele różnych nazw.\"\n\n**Werdykt: PRAWDA** ✓\n\nNa jednym serwerze (jeden adres IP) może być **wiele domen** - to mechanizm **wirtualnego hostingu**. Przykładowo, jedna maszyna na IP 192.168.1.10 może obsługiwać domeny `example.com`, `firma.pl`, `blog.eu` - wszystkie wskazują na ten sam IP. Serwer WWW rozróżnia żądania po nagłówku `Host:` w HTTP.\n\n### Stwierdzenie 3: \"Przy zmianie adresu IP komputera pełniącego funkcję serwera WWW jest konieczna zmiana nazwy domeny internetowej.\"\n\n**Werdykt: FAŁSZ** ✗\n\nWręcz przeciwnie - **kluczową zaletą DNS** jest możliwość zmiany IP **BEZ zmiany nazwy domeny**. Administrator po prostu aktualizuje **rekord A** (lub AAAA dla IPv6) w bazie DNS - domena pozostaje ta sama, ale wskazuje na nowy adres IP. Użytkownik tego nie zauważy.\n\n### Stwierdzenie 4: \"System DNS ma jedną centralną bazę danych adresów IP i nazw.\"\n\n**Werdykt: FAŁSZ** ✗\n\nDNS to **system rozproszony i hierarchiczny**, NIE jedna centralna baza:\n- **Serwery root** (13 logicznych, fizycznie wiele tysięcy) - szczyt hierarchii.\n- **Serwery TLD** (Top-Level Domain) - np. `.pl`, `.com`, `.eu`.\n- **Serwery autoritatywne** dla konkretnych domen (np. `maturazai.pl`).\n- **Serwery cache/resolvery** (np. ISP, Google 8.8.8.8, Cloudflare 1.1.1.1).\n\nGdyby DNS był centralny, awaria jednej maszyny zablokowałaby cały Internet. Rozproszenie zapewnia **odporność** i **skalowalność**.\n\n## Sposób 2 - wizualizacja hierarchii DNS\n\n[root .]\n.pl .com .org (serwery TLD)\nmaturazai.pl (serwer autoritatywny)\nwww.maturazai.pl → 104.21.x.x (rekord A)\n\nZapytanie typowego klienta:\n1. \"Co to www.maturazai.pl?\" → lokalny resolver (np. 8.8.8.8).\n2. Resolver pyta root → \"idź do serwera .pl\".\n3. Pyta .pl → \"idź do autoritatywnego serwera maturazai.pl\".\n4. Pyta autoritatywny → \"to jest 104.21.x.x\".\n5. Resolver zwraca odpowiedź klientowi i CACHEUJE wynik (TTL).\n\n## Reference informatyczny - DNS\n\n> Reference - DNS (Domain Name System):\n> - **Cel:** mapuje czytelne nazwy domen na adresy IP (i odwrotnie).\n> - **Architektura:** rozproszona, hierarchiczna (drzewo).\n> - **Port:** 53 (UDP najczęściej, TCP dla dużych odpowiedzi i transferów strefy).\n> - **Typy rekordów:**\n> - `A` - IPv4 dla nazwy.\n> - `AAAA` - IPv6 dla nazwy.\n> - `CNAME` - alias dla innej nazwy.\n> - `MX` - serwer pocztowy.\n> - `NS` - serwer nazw dla domeny.\n> - `TXT` - dowolny tekst (np. SPF, DKIM).\n> - `PTR` - odwrotne DNS (IP → nazwa).\n> - **TTL** (Time To Live) - jak długo wynik jest cache'owany.\n> - **Korzyści:** dynamiczne IP bez zmiany nazwy, wirtualny hosting, load balancing.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 3.3, max 1 pkt):\n> - **1 pkt** - wszystkie 4 odpowiedzi (P, P, F, F)\n> - **0 pkt** - niepełna lub błędna\n\n## Dlaczego inne odpowiedzi błędne - pułapki\n\n| Stw. | Pułapka | Trafna ocena |\n| 1 | - | P (definicja) |\n| 2 | Mylenie z odwrotnym kierunkiem (kilka IP na 1 nazwie - to też prawda, ale tu chodzi o drugi kierunek) | P |\n| 3 | Założenie, że IP i nazwa są \"sztywno powiązane\" | F (DNS dynamicznie aktualizuje rekordy) |\n| 4 | Założenie, że \"globalny system\" = \"centralna baza\" | F (DNS rozproszony) |\n\n## Typowe pułapki\n\n- **Mylenie DNS z DHCP** - DHCP przydziela adresy IP w sieci lokalnej, DNS mapuje nazwy.\n- **Mylenie DNS z hostami pliku `/etc/hosts`** - w `hosts` możesz lokalnie nadpisać DNS dla testów, ale to nie jest sam DNS.\n- **\"Jedna centralna baza\"** - częsta intuicja, ale BŁĘDNA. DNS to rozproszony system tysięcy serwerów.\n- **\"DNS i URL to to samo\"** - URL zawiera nazwę domeny, ale to dwie różne rzeczy.\n\n## Złożoność obliczeniowa\n\n- Czas zapytania DNS: średnio **~10-50 ms** (z cache lokalnym, lub <1ms gdy resolver lokalny zna odpowiedź).\n- Skalowanie: hierarchiczność umożliwia obsługę **miliardów domen** bez wąskiego gardła.","image":"img/informatyka-2019-maj-matura-rozszerzona/zad-3.3.webp","solution_image":null,"topics":null,"page_from":7,"source":"ocr","answer_source":null,"answer_text_source":"ocr","solution_source":"maturazai","text_source":"ocr","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/4.1","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"4.1","points":3,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Zadanie 4. Liczby\n\nW pliku liczby.txt zapisano 500 liczb całkowitych dodatnich po jednej w każdym wierszu. Każda liczba jest z zakresu od 1 do 100 000. Napisz program(-y) dający(-e) odpowiedzi do poniższych zadań. Zapisz uzyskane odpowiedzi w pliku wyniki4.txt, poprzedzając każdą z nich numerem odpowiedniego zadania.\n\nUwaga: Plik przyklad.txt zawiera przykładowe dane spełniające warunki zadania. Odpowiedzi dla danych z tego pliku są podane pod treściami zadań.\n\nPodaj, ile z podanych liczb jest potęgami liczby 3 (czyli liczbami postaci 1 = 3⁰, 3 = 3¹, 9 = 3² itd.).\n\nDla pliku przyklad.txt odpowiedź wynosi 2.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Liczba potęg liczby 3 w pliku liczby.txt: 18**\n\nPotęgi 3 w zakresie [1, 100 000]: 3⁰=1, 3¹=3, 3²=9, 3³=27, 3⁴=81, 3⁵=243, 3⁶=729, 3⁷=2187, 3⁸=6561, 3⁹=19683, 3¹⁰=59049 (3¹¹=177147 > 100 000).\n\n## Sposób 1 - implementacja Python (rekomendowana)\n\n**Idea 1: prekomputacja potęg + sprawdzenie przynależności.**\n\n```python\n# Wszystkie potęgi 3 ≤ 100000\npotegi = set()\np = 1\nwhile p <= 100000:\npotegi.add(p)\np *= 3\n# potegi = {1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049}\n\nlicznik = 0\nwith open('liczby.txt', encoding='utf-8') as f:\nfor linia in f:\nn = int(linia.strip())\nif n in potegi:\nlicznik += 1\n\nprint(licznik) # 18\n\n**Idea 2: dzielenie przez 3 dopóki się da.**\n\n```python\ndef jest_potega_3(n):\nwhile n % 3 == 0:\nn //= 3\nreturn n == 1\n\nlicznik = 0\nwith open('liczby.txt') as f:\nfor linia in f:\nn = int(linia.strip())\nif jest_potega_3(n):\nlicznik += 1\nprint(licznik) # 18\n\n## Sposób 2 - implementacja Pascal\n\n```pascal\nprogram PotegiTrojki;\nvar\nf: TextFile;\nn, licznik, m: LongInt;\nbegin\nAssignFile(f, 'liczby.txt');\nReset(f);\nlicznik := 0;\nwhile not Eof(f) do\nbegin\nReadLn(f, n);\nm := n;\nwhile (m mod 3 = 0) do m := m div 3;\nif m = 1 then licznik := licznik + 1;\nend;\nCloseFile(f);\nWriteLn('Liczba potęg 3: ', licznik);\nend.\n\n## Sposób 3 - implementacja C++\n\n```cpp\n#include <iostream>\n#include <fstream>\nusing namespace std;\n\nbool jestPotega3(long long n) {\nwhile (n % 3 == 0) n /= 3;\nreturn n == 1;\n}\n\nint main() {\nifstream plik(\"liczby.txt\");\nlong long n;\nint licznik = 0;\nwhile (plik >> n) {\nif (jestPotega3(n)) licznik++;\n}\ncout << \"Liczba potęg 3: \" << licznik << endl;\nreturn 0;\n}\n\n## Sposób 4 - weryfikacja dla przyklad.txt\n\nDla `przyklad.txt` odpowiedź wynosi **2** (zgodnie z treścią zadania). Oznacza to, że w pliku przykładowym są dokładnie 2 liczby będące potęgami 3 (np. 1 i 27).\n\n## Reference informatyczny - test na potęgę liczby\n\n> Reference - Sprawdzanie czy n jest potęgą k:\n> - **Algorytm dzielenia:** dzielimy n przez k dopóki dzieli się bez reszty. Jeśli zakończymy z n=1 → jest potęgą.\n> - **Złożoność:** O(log_k(n)).\n> - **Wariant prekomputacji:** generuj wszystkie potęgi k ≤ MAX, sprawdź przynależność. Złożoność: O(1) na zapytanie (z hashsetem).\n> - **Wariant logarytmiczny (z float):** `log(n)/log(k) ∈ Z`? - ALE niedokładny przez błędy floating-point. NIE używać w zadaniach CKE.\n> - **Dla potęgi 2:** trik `(n & (n-1)) == 0` (bit-tricky).\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 4.1, max 3 pkt):\n> - **3 pkt** - prawidłowa odpowiedź (18)\n> - **2 pkt** - wynik różniący się o 1 (np. pominięcie 1=3⁰ albo licznik od 0)\n> - **1 pkt** - wynik mniejszy o 2 lub 3 (pominięcie 2-3 liczb)\n> - **0 pkt** - błędna lub brak\n\n## Typowe pułapki\n\n- **Pominięcie 1 = 3⁰** - częsty błąd: \"potęgi to 3, 9, 27 \" bez liczby 1. Treść WYRAŹNIE pisze \"liczbami postaci 1 = 3⁰\".\n- **Floating-point** w teście `log3(n) ∈ Z` - błędy zaokrąglenia mogą dać fałszywe wyniki.\n- **`n % 3 == 0` na liczbach typu 12, 15** - to nie są potęgi 3, ale dzielą się przez 3. KLUCZ: po wszystkich dzieleniach trzeba zostać z 1.\n- **Off-by-one** przy liczeniu (start od 0 vs 1).\n- **Niepoprawne czytanie pliku** - pomylenie z `print` zamiast czytania linii.\n\n## Złożoność obliczeniowa\n\n- Czytanie pliku: O(n) - n = 500 wierszy.\n- Test na potęgę 3 metodą dzielenia: O(log₃(max)) = O(log(100000)) ≈ 11 operacji.\n- **Łączna złożoność: O(n · log(max)) ≈ 5500 operacji** (bardzo szybko).\n- Pamięć: O(1) (lub O(log(max)) dla zbioru potęg).","image":null,"solution_image":null,"topics":null,"page_from":null,"source":"maturazai","answer_source":null,"answer_text_source":null,"solution_source":"maturazai","text_source":"maturazai","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/4.2","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"4.2","points":4,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Kontekst - patrz zadanie 4.1.\n\nSilnią liczby naturalnej k większej od 0 nazywamy wartość iloczynu 1·2 k i oznaczamy przez k!. Przyjmujemy, że 0!=1. Zatem mamy:\n- 0! = 1\n- 1! = 1\n- 2! = 1·2 = 2\n- 3! = 1·2·3 = 6\n- 4! = 1·2·3·4 = 24 itd.\n\nDowolną liczbę naturalną możemy rozbić na cyfry, a następnie policzyć sumę silni jej cyfr. Na przykład dla liczby 343 mamy 3! + 4! + 3! = 6 + 24 + 6 = 36.\n\nW pliku przyklad.txt znajduje się jedna taka liczba: 145 (1!+4!+5! =1+24+120 =145).\n\nPodaj, w kolejności ich występowania w pliku liczby.txt, wszystkie liczby, które są równe sumie silni swoich cyfr.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Liczby z pliku liczby.txt równe sumie silni swoich cyfr (w kolejności występowania):**\n\n2\n145\n1\n40585\n\n**Te liczby to tzw. \"factorions\" - w dziesiętnym wszystkich jest dokładnie 4: 1, 2, 145, 40585.**\n\n## Sposób 1 - implementacja Python\n\n```python\n# Precomputed silnie 0! 9!\nsilnie = [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]\n\ndef suma_silni_cyfr(n):\ns = 0\nif n == 0:\nreturn 1 # 0! = 1\nwhile n > 0:\ns += silnie[n % 10]\nn //= 10\nreturn s\n\nwyniki = []\nwith open('liczby.txt', encoding='utf-8') as f:\nfor linia in f:\nn = int(linia.strip())\nif suma_silni_cyfr(n) == n:\nwyniki.append(n)\n\nfor w in wyniki:\nprint(w)\n# 2\n# 145\n# 1\n# 40585\n\n**Weryfikacja:**\n- 1: 1! = 1 ✓\n- 2: 2! = 2 ✓\n- 145: 1! + 4! + 5! = 1 + 24 + 120 = **145** ✓\n- 40585: 4! + 0! + 5! + 8! + 5! = 24 + 1 + 120 + 40320 + 120 = **40585** ✓\n\n## Sposób 2 - implementacja Pascal\n\n```pascal\nprogram SumaSilniCyfr;\nvar\nf: TextFile;\nn, m, suma, cyfra, i: LongInt;\nsilnie: array[0 9] of LongInt;\nbegin\nsilnie[0] := 1;\nfor i := 1 to 9 do silnie[i] := silnie[i-1] * i;\nAssignFile(f, 'liczby.txt');\nReset(f);\nwhile not Eof(f) do\nbegin\nReadLn(f, n);\nm := n; suma := 0;\nif m = 0 then suma := 1\nelse while m > 0 do\nbegin\ncyfra := m mod 10;\nsuma := suma + silnie[cyfra];\nm := m div 10;\nend;\nif suma = n then WriteLn(n);\nend;\nCloseFile(f);\nend.\n\n## Sposób 3 - implementacja C++\n\n```cpp\n#include <iostream>\n#include <fstream>\nusing namespace std;\n\nint silnie[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};\n\nlong long sumaSilniCyfr(long long n) {\nif (n == 0) return 1;\nlong long s = 0;\nwhile (n > 0) {\ns += silnie[n % 10];\nn /= 10;\n}\nreturn s;\n}\n\nint main() {\nifstream plik(\"liczby.txt\");\nlong long n;\nwhile (plik >> n) {\nif (sumaSilniCyfr(n) == n) cout << n << endl;\n}\nreturn 0;\n}\n\n## Reference informatyczny - wydobywanie cyfr liczby\n\n> Reference - Algorytm na rozkład liczby na cyfry:\n> ```\n> dopóki n > 0\n> cyfra ← n mod 10\n> n ← n div 10\n> ```\n> Złożoność: O(log₁₀(n)) - liczba cyfr.\n>\n> Reference - Silnia:\n> - 0! = 1, n! = n · (n-1)! dla n > 0.\n> - Rosnie szybko: 10! = 3 628 800, 12! przekracza 32-bit int.\n> - Pre-kompute: tablica silni[0 9] = [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880].\n>\n> Reference - Factoriony:\n> - W dziesiętnym SĄ TYLKO 4 factoriony: 1, 2, 145, 40585. Udowodniono, że więcej nie istnieje.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 4.2, max 4 pkt):\n> - **4 pkt** - wszystkie 4 liczby (2, 145, 1, 40585) w prawidłowej kolejności\n> - **1 pkt** za każdą poprawną liczbę w wyniku\n> - **0 pkt** - błędna albo brak\n\n## Typowe pułapki\n\n- **Pominięcie 0! = 1** - bez tego dla liczby 40585 wynik byłby 23+1+120+40320+120 = 40584 (lub mocno błędny).\n- **Kolejność w wyniku** - musi być w kolejności pojawiania się w pliku liczby.txt (nie alfabetycznie/numerycznie).\n- **Złe wpisanie tablicy silni** - najczęstszy błąd: pomylenie 5! = 120 z 6! = 720.\n- **Overflow w Pascal/C++** - 9! = 362880 mieści się w 32-bit int, ale uważać dla wielocyfrowych liczb.\n- **Brak warunku zatrzymania pętli** - gdy n=0 (liczba 0 nie pojawi się w danych, bo zakres 1-100000).\n\n## Złożoność obliczeniowa\n\n- Wczytanie pliku: O(n) - 500 wierszy.\n- Obliczenie sumy silni cyfr: O(log n) ≈ 6 operacji (max 6 cyfr).\n- Łącznie: **O(n · log(max))** ≈ 3000 operacji - błyskawicznie.\n- Pamięć: O(1) (tablica silni stała).","image":null,"solution_image":null,"topics":null,"page_from":null,"source":"maturazai","answer_source":null,"answer_text_source":null,"solution_source":"maturazai","text_source":"maturazai","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/4.3","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"4.3","points":5,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Kontekst - patrz zadanie 4.1.\n\nUwaga: Możesz skorzystać z zależności NWD(a, b, c) = NWD(NWD(a, b), c).\n\nPrzykład:\nDla liczb 3, 7, 4, 6, 10, 2, 5 odpowiedzią jest 4 (pierwsza liczba ciągu), 4 (długość ciągu) i 2 (największy wspólny dzielnik), natomiast dla liczb 5, 70, 28, 42, 98, 1 odpowiedzią jest 70 (pierwsza liczba ciągu), 4 (długość ciągu) i 14 (największy wspólny dzielnik).\n\nOdpowiedź dla pliku przyklad.txt: pierwsza liczba ciągu 90, długość 5, największy wspólny dzielnik 10.\n\nW pliku liczby.txt znajdź najdłuższy ciąg liczb występujących kolejno po sobie i taki, że największy wspólny dzielnik ich wszystkich jest większy od 1 (innymi słowy: istnieje taka liczba całkowita większa od 1, która jest dzielnikiem każdej z tych liczb).\n\nJako odpowiedź podaj wartość pierwszej liczby w takim ciągu, długość ciągu oraz największą liczbę całkowitą, która jest dzielnikiem każdej liczby w tym ciągu. W pliku z danymi jest tylko jeden taki ciąg o największej długości.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Najdłuższy ciąg z NWD > 1 w pliku liczby.txt:**\n- **Pierwsza liczba ciągu: 31968**\n- **Długość ciągu: 150**\n- **Największy wspólny dzielnik: 74**\n\n## Sposób 1 - implementacja Python\n\n**Idea:** przeglądamy ciąg od lewej. Utrzymujemy bieżący NWD i długość. Gdy NWD spadnie do 1 - kończymy ciąg, sprawdzamy czy jest najdłuższy, i zaczynamy nowy ciąg od bieżącej liczby. Wykorzystujemy własność: **NWD(a, b, c) = NWD(NWD(a, b), c)**.\n\n```python\nfrom math import gcd\n\nwith open('liczby.txt', encoding='utf-8') as f:\nliczby = [int(linia) for linia in f]\n\nnajdluzszy_start_idx = 0\nnajdluzsza_dlugosc = 1\nnajdluzszy_nwd = liczby[0]\n\nbiezacy_start = 0\nbiezacy_nwd = liczby[0]\n\nfor i in range(1, len(liczby)):\nnowy_nwd = gcd(biezacy_nwd, liczby[i])\nif nowy_nwd > 1:\nbiezacy_nwd = nowy_nwd\ndlugosc = i - biezacy_start + 1\nif dlugosc > najdluzsza_dlugosc:\nnajdluzsza_dlugosc = dlugosc\nnajdluzszy_start_idx = biezacy_start\nnajdluzszy_nwd = biezacy_nwd\nelse:\n# nowy ciąg startuje od liczby[i]\nbiezacy_start = i\nbiezacy_nwd = liczby[i]\n\nprint(f'pierwsza liczba: {liczby[najdluzszy_start_idx]}')\nprint(f'długość: {najdluzsza_dlugosc}')\nprint(f'dzielnik: {najdluzszy_nwd}')\n# pierwsza liczba: 31968\n# długość: 150\n# dzielnik: 74\n\n**Algorytm NWD (Euklides):**\n```python\ndef nwd(a, b):\nwhile b > 0:\na, b = b, a % b\nreturn a\n\n## Sposób 2 - implementacja Pascal\n\n```pascal\nprogram NajdluzszyCiagNWD;\nvar\nf: TextFile;\nliczby: array[1 500] of LongInt;\ni, n: Integer;\nbiezacyStart, biezacyNWD, najStart, najDl, najNWD, nowyNWD, dl: LongInt;\n\nfunction NWD(a, b: LongInt): LongInt;\nvar t: LongInt;\nbegin\nwhile b > 0 do begin t := b; b := a mod b; a := t; end;\nNWD := a;\nend;\n\nbegin\nAssignFile(f, 'liczby.txt');\nReset(f);\nn := 0;\nwhile not Eof(f) do begin Inc(n); ReadLn(f, liczby[n]); end;\nCloseFile(f);\n\nbiezacyStart := 1; biezacyNWD := liczby[1];\nnajStart := 1; najDl := 1; najNWD := liczby[1];\n\nfor i := 2 to n do\nbegin\nnowyNWD := NWD(biezacyNWD, liczby[i]);\nif nowyNWD > 1 then\nbegin\nbiezacyNWD := nowyNWD;\ndl := i - biezacyStart + 1;\nif dl > najDl then\nbegin\nnajDl := dl; najStart := biezacyStart; najNWD := biezacyNWD;\nend;\nend\nelse\nbegin\nbiezacyStart := i; biezacyNWD := liczby[i];\nend;\nend;\n\nWriteLn('pierwsza: ', liczby[najStart]);\nWriteLn('długość: ', najDl);\nWriteLn('dzielnik: ', najNWD);\nend.\n\n## Sposób 3 - implementacja C++\n\n```cpp\n#include <iostream>\n#include <fstream>\n#include <vector>\nusing namespace std;\n\nlong long nwd(long long a, long long b) {\nwhile (b > 0) { long long t = b; b = a % b; a = t; }\nreturn a;\n}\n\nint main() {\nifstream plik(\"liczby.txt\");\nvector<long long> liczby;\nlong long x;\nwhile (plik >> x) liczby.push_back(x);\n\nlong long biezacyNWD = liczby[0], najNWD = liczby[0];\nint biezacyStart = 0, najStart = 0, najDl = 1;\n\nfor (int i = 1; i < (int)liczby.size(); i++) {\nlong long nowy = nwd(biezacyNWD, liczby[i]);\nif (nowy > 1) {\nbiezacyNWD = nowy;\nint dl = i - biezacyStart + 1;\nif (dl > najDl) {\nnajDl = dl;\nnajStart = biezacyStart;\nnajNWD = biezacyNWD;\n}\n} else {\nbiezacyStart = i;\nbiezacyNWD = liczby[i];\n}\n}\n\ncout << \"pierwsza: \" << liczby[najStart] << endl;\ncout << \"długość: \" << najDl << endl;\ncout << \"dzielnik: \" << najNWD << endl;\nreturn 0;\n}\n\n## Weryfikacja na przykładzie\n\nDla `przyklad.txt`: pierwsza 90, długość 5, dzielnik 10. Oznacza, że istnieje ciąg 5 kolejnych liczb (zaczynający się od 90), których wszystkie wartości są wielokrotnościami 10.\n\nDla przykładu z treści: `3, 7, 4, 6, 10, 2, 5`:\n- 3,7 - gcd=1 (koniec ciągu 3 samodzielnie). Start nowego od 7. Ale gcd(7,4)=1 → start od 4.\n- 4,6 → gcd=2. 4,6,10 → gcd=2. 4,6,10,2 → gcd=2. 4,6,10,2,5 → gcd=1. → Ciąg: 4,6,10,2, długość 4, gcd=2 ✓.\n\n## Reference informatyczny - NWD (GCD)\n\n> Reference - Algorytm Euklidesa:\n> ```\n> NWD(a, b):\n> dopóki b > 0\n> a, b = b, a mod b\n> zwróć a\n> ```\n> Złożoność: O(log min(a, b)).\n>\n> Reference - Własności NWD:\n> - NWD(a, b) = NWD(b, a mod b).\n> - NWD(a, 0) = a.\n> - NWD(a, b, c) = NWD(NWD(a, b), c).\n> - NWD(a, b) ≥ 1 zawsze.\n> - NWD(a, b) > 1 ⟺ a i b mają wspólny dzielnik > 1.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 4.3, max 5 pkt):\n> - **1 pkt** - pierwsza liczba w ciągu (31968)\n> - **2 pkt** - długość ciągu (150); 1 pkt jeśli różni się o 1 (np. liczenie od 0)\n> - **2 pkt** - wspólny dzielnik (74)\n> - **4 pkt** - za wariant (56536, 149, 74) - wynik z błędem off-by-one\n> - **0 pkt** - błędna albo brak\n\n## Typowe pułapki\n\n- **Resetowanie NWD po nowym elemencie ZAMIAST liczenia od zera** - gdy NWD spadnie do 1, musisz zacząć NOWY ciąg od bieżącej liczby (NIE od następnej).\n- **Aktualizacja długości tylko gdy NWD > 1** - wybór maksymalnej długości musi działać dla najdłuższego ciągu z NWD > 1, NIE każdego okna.\n- **Off-by-one przy długości** - długość = i - start + 1 (gdy indeksowanie od 0).\n- **Pierwsza liczba = `liczby[start]`** - pamiętaj, że pytanie pyta o WARTOŚĆ pierwszej liczby, nie jej indeks.\n- **Złe NWD dla pierwszego ciągu jednoelementowego** - start jako liczba pojedyncza ma NWD = sama ta liczba.\n\n## Złożoność obliczeniowa\n\n- Czytanie pliku: O(n), n = 500.\n- Główna pętla: O(n) iteracji, w każdej NWD: O(log(max)) ≈ 17 operacji dla wartości do 100 000.\n- **Łącznie: O(n · log(max))** ≈ 8500 operacji.\n- Pamięć: O(n) na tablicę liczb (lub O(1) gdy czytamy streaming).","image":null,"solution_image":null,"topics":null,"page_from":null,"source":"maturazai","answer_source":null,"answer_text_source":null,"solution_source":"maturazai","text_source":"maturazai","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/5.1","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"5.1","points":2,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Zadanie 5. Chmury\n\nNaukowcy śledzą zmiany pogody na odległej planecie. Chmury występujące na niebie tej planety podzielono na dwie kategorie, nazwane przez analogię do ziemskich cirrusami (C) i stratusami (S). W każdej z kategorii chmury są klasyfikowane względem wielkości od 1 do 5. Mamy zatem chmury dziesięciu rodzajów: C1, C2, C3, C4 i C5 oraz S1, S2, S3, S4 i S5. Na tej planecie w jednym dniu mogą występować chmury tylko jednego rodzaju.\n\nW każdym z 500 kolejnych dni stacja badawcza umiejscowiona na planecie mierzyła temperaturę w stopniach oraz określała rodzaj chmur. Dane te zawarte są w kolejnych wierszach pliku pogoda.txt. Każdy wiersz pliku pogoda.txt zawiera kolejno:\n- numer dnia (od 1 do 500),\n- zmierzoną temperaturę (z dokładnością do jednego miejsca po przecinku, temperatura nigdy nie spada poniżej zera),\n- wielkość opadu, jaki miał miejsce tego dnia (w milimetrach, zaokrąglony do liczby całkowitej),\n- kategorię chmur (C, S lub 0 - jeśli dzień był bezchmurny),\n- wielkość chmur (od 1 do 5 lub 0 - jeśli dzień był bezchmurny).\n\nDane oddzielone są średnikami, pierwszy wiersz jest wierszem nagłówkowym.\n\nPrzykład:\nDzien;Temperatura;Opad;Kategoria_chmur;Wielkosc_chmur\n1;19;0;0;0\n2;22;1;C;1\n3;23,6;4;C;1\n\nW dniu 301. kamera na stacji badawczej się zepsuła i od tego dnia stacja raportowała wszystkie dni jako „bezchmurne”, temperatura i opady jednak dalej były poprawnie mierzone.\n\nPodaj liczbę dni o temperaturze większej lub równej 20 stopni i jednocześnie o opadzie mniejszym lub równym 5 mm.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Liczba dni: 63**\n\n## Sposób 1 - Python z czytaniem CSV\n\n```python\nlicznik = 0\nwith open('pogoda.txt', encoding='utf-8') as f:\nnaglowek = f.readline() # pomijamy nagłówek\nfor linia in f:\npola = linia.strip().split(';')\n# pola: Dzien, Temperatura, Opad, Kategoria_chmur, Wielkosc_chmur\ntemperatura = float(pola[1].replace(',', '.'))\nopad = int(pola[2])\nif temperatura >= 20 and opad <= 5:\nlicznik += 1\n\nprint(licznik) # 63\n\n**WAŻNE:** w pliku CSV polski format dziesiętny (`19,3` zamiast `19.3`) - trzeba zamienić `,` na `.` przed `float()`.\n\n## Sposób 2 - arkusz kalkulacyjny (LibreOffice/Excel)\n\nW arkuszu (np. komórka G2):\n=LICZ.WARUNKI(B2:B501; \">=20\"; C2:C501; \"<=5\")\n\nGdzie:\n- `B2:B501` - kolumna temperatury (500 dni + nagłówek)\n- `C2:C501` - kolumna opadu\n- Pierwszy warunek: temperatura ≥ 20\n- Drugi warunek: opad ≤ 5\n\n**Wynik: 63**\n\nAlternatywnie z formułą tablicową:\n=SUMA((B2:B501>=20)*(C2:C501<=5)) {wciśnij Ctrl+Shift+Enter}\n\n## Sposób 3 - SQL (po imporcie pogoda.txt do bazy)\n\n```sql\nSELECT COUNT(*) AS liczba_dni\nFROM pogoda\nWHERE Temperatura >= 20 AND Opad <= 5;\n-- Wynik: 63\n\n## Sposób 4 - implementacja Pascal\n\n```pascal\nprogram CieplyMaloOpadu;\nvar\nf: TextFile;\nlinia: String;\nlicznik, dzien, opad, wielkosc: Integer;\ntemp: Real;\nkat: Char;\nbegin\nAssignFile(f, 'pogoda.txt');\nReset(f);\nReadLn(f, linia); // nagłówek\nlicznik := 0;\nwhile not Eof(f) do\nbegin\nReadLn(f, linia);\n// (parsowanie CSV ; pominięte dla zwięzłości)\nif (temp >= 20) and (opad <= 5) then licznik := licznik + 1;\nend;\nCloseFile(f);\nWriteLn('Liczba dni: ', licznik);\nend.\n\n## Reference informatyczny - analiza danych w arkuszu\n\n> Reference - Funkcje warunkowe w arkuszu kalkulacyjnym:\n> - `=LICZ.JEŻELI(zakres; kryterium)` - liczy komórki spełniające 1 warunek.\n> - `=LICZ.WARUNKI(zakres1; kryt1; zakres2; kryt2; )` - wielowarunkowe.\n> - `=SUMA.JEŻELI(zakres; kryt; suma_zakres)` - suma B gdy A spełnia warunek.\n> - `=SUMA.WARUNKÓW(suma_z; zakres1; kryt1; )` - suma wielowarunkowa.\n>\n> Excel angielski:\n> - COUNTIF, COUNTIFS, SUMIF, SUMIFS - odpowiedniki polskie.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 5.1, max 2 pkt):\n> - **2 pkt** - poprawna odpowiedź (63)\n> - **1 pkt** - odpowiedź wynikająca z nierówności ostrych zamiast nieostrych:\n> - 51 (obie nierówności ostre - temp > 20, opad < 5)\n> - 59 (temp ostre, opad nieostre)\n> - 54 (temp nieostre, opad ostre)\n> - **0 pkt** - błędna lub brak\n\n## Typowe pułapki\n\n- **`>` zamiast `>=`** - TREŚĆ wyraźnie pisze \"większej lub równej\" (≥) i \"mniejszej lub równej\" (≤). Pominięcie równości = zła odpowiedź.\n- **Format dziesiętny w CSV** - w polskim CSV jest `,` zamiast `.`. W Python: `replace(',', '.')` przed `float()`.\n- **Pomylenie kolumn** - opad to kolumna 3 (indeks 2), kategoria chmur to kol. 4.\n- **Liczenie nagłówka** - pierwszy wiersz to nazwy pól, nie dane.\n- **Pominięcie warunku `<=`** - pisanie `< 5` zamiast `<= 5` daje 54 zamiast 63.\n\n## Złożoność obliczeniowa\n\n- Przegląd 500 wierszy: **O(n) = O(500)** - natychmiastowe.\n- Pamięć: O(1) (streaming) lub O(n) jeśli ładujemy całość.","image":null,"solution_image":null,"topics":null,"page_from":null,"source":"maturazai","answer_source":null,"answer_text_source":null,"solution_source":"maturazai","text_source":"maturazai","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/5.2","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"5.2","points":2,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Kontekst - patrz zadanie 5.1.\n\nNa przykład dla danych:\ndzień temperatura\n34 3,7\n35 3,4\n**36 3,5**\n**37 3,6**\n**38 3,7**\n39 3,5\npierwszym dniem ciągu spełniającym warunek zadania jest dzień 36, a ostatnim - 38.\n\nZnajdź najdłuższy ciąg kolejnych dni, w których temperatura zmierzona każdego dnia jest wyższa niż temperatura dnia poprzedniego. Jest tylko jeden taki ciąg. Podaj numer pierwszego i numer ostatniego dnia w takim ciągu.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Najdłuższy ciąg dni o monotonicznie rosnącej temperaturze:**\n- **Pierwszy dzień: 448**\n- **Ostatni dzień: 455**\n\n(Długość ciągu: 455 - 448 + 1 = **8 dni**)\n\n## Sposób 1 - Python (algorytm okna o jednym przebiegu)\n\n```python\n# Wczytaj dane: lista (dzien, temperatura)\ndane = []\nwith open('pogoda.txt', encoding='utf-8') as f:\nf.readline() # nagłówek\nfor linia in f:\npola = linia.strip().split(';')\ndzien = int(pola[0])\ntemp = float(pola[1].replace(',', '.'))\ndane.append((dzien, temp))\n\nnaj_start = naj_end = 0\nnaj_dl = 1\nbiezacy_start = 0\n\nfor i in range(1, len(dane)):\nif dane[i][1] > dane[i-1][1]:\n# kontynuacja rosnącego ciągu\ndl = i - biezacy_start + 1\nif dl > naj_dl:\nnaj_dl = dl\nnaj_start = biezacy_start\nnaj_end = i\nelse:\n# przerwanie - nowy ciąg startuje od i\nbiezacy_start = i\n\nprint(f'Pierwszy dzień: {dane[naj_start][0]}') # 448\nprint(f'Ostatni dzień: {dane[naj_end][0]}') # 455\n\n## Sposób 2 - arkusz kalkulacyjny (LibreOffice/Excel)\n\n**Pomocnicza kolumna F (długość bieżącego rosnącego ciągu):**\nF2 = 1\nF3 = JEŻELI(B3 > B2; F2 + 1; 1)\nSkopiuj F3 w dół do F501.\n\n**Znalezienie maksimum i jego pozycji:**\nG1 = MAX(F2:F501) # długość najdłuższego ciągu (= 8)\nG2 = PODAJ.POZYCJĘ(G1; F2:F501; 0) # wiersz końca ciągu\nNumer pierwszego dnia = G2 - G1 + 1 + 1 (offset wiersza nagłówka).\n\nKonkretnie: G1 = 8, G2 = 454 (indeks od 1 w pomocniczej kolumnie F2:F501), więc:\n- ostatni dzień: 455 (numer dnia z kolumny A)\n- pierwszy dzień: 448.\n\n## Sposób 3 - implementacja Pascal\n\n```pascal\nprogram NajdluzszyRosnacyCiag;\nvar\nf: TextFile;\nlinia: String;\ntemp: array[1 500] of Real;\ni, start, najStart, najEnd, najDl, dl: Integer;\nbegin\nAssignFile(f, 'pogoda.txt');\nReset(f);\nReadLn(f, linia); // nagłówek\nfor i := 1 to 500 do\nbegin\n// parsowanie linii (pomijam dla zwięzłości)\n// temp[i] :=\nend;\nCloseFile(f);\n\nstart := 1; najStart := 1; najEnd := 1; najDl := 1;\nfor i := 2 to 500 do\nbegin\nif temp[i] > temp[i-1] then\nbegin\ndl := i - start + 1;\nif dl > najDl then\nbegin\nnajDl := dl; najStart := start; najEnd := i;\nend;\nend\nelse\nstart := i;\nend;\n\nWriteLn('Pierwszy: ', najStart); // 448\nWriteLn('Ostatni: ', najEnd); // 455\nend.\n\n## Sposób 4 - implementacja C++\n\n```cpp\n#include <iostream>\n#include <fstream>\n#include <vector>\n#include <sstream>\nusing namespace std;\n\nint main() {\nifstream plik(\"pogoda.txt\");\nstring linia;\ngetline(plik, linia); // nagłówek\nvector<double> temp;\nwhile (getline(plik, linia)) {\n// parsowanie po średnikach\n// temp.push_back( );\n}\n\nint start = 0, najStart = 0, najEnd = 0, najDl = 1;\nfor (int i = 1; i < (int)temp.size(); i++) {\nif (temp[i] > temp[i-1]) {\nint dl = i - start + 1;\nif (dl > najDl) {\nnajDl = dl; najStart = start; najEnd = i;\n}\n} else start = i;\n}\ncout << \"Pierwszy: \" << najStart+1 << endl; // 448\ncout << \"Ostatni: \" << najEnd+1 << endl; // 455\nreturn 0;\n}\n\n## Reference informatyczny - najdłuższy podciąg rosnący kolejnych\n\n> Reference - Klasa problemu \"Longest run\" (kolejne rosnące):\n> - WAŻNE: To NIE jest LIS (Longest Increasing Subsequence). To **najdłuższy ciągły fragment rosnący** - wymaga ciągłości pozycji.\n> - Algorytm: jedno-przebiegowy O(n) - utrzymuj długość bieżącego rosnącego ciągu, resetuj gdy warunek złamany.\n> - Złożoność: O(n) czasu, O(1) pamięci.\n> - LIS to zupełnie inny problem: dopuszcza wybór niesąsiednich elementów, rozwiązywany w O(n log n).\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 5.2, max 2 pkt):\n> - **2 pkt** - pełna odpowiedź, w tym:\n> - 1 pkt - poprawny początek (448)\n> - 1 pkt - poprawny koniec (455)\n> - **0 pkt** - błędna lub brak\n\n## Typowe pułapki\n\n- **`>=` zamiast `>`** - treść mówi WYŻSZA niż poprzednia, czyli ostre `>`. Pominięcie tego daje dłuższe ciągi z plateau (nie rosnące).\n- **Off-by-one przy resetowaniu start** - gdy warunek złamany, nowy ciąg startuje od `i` (NIE od `i+1`!), bo dzień `i` to potencjalny początek nowego ciągu.\n- **Format dziesiętny** - temperatura ma postać `19,3` (przecinek!), w Pythonie zamień na `.` przed konwersją.\n- **Włączenie nagłówka** - pomiń pierwszą linię.\n- **\"Najdłuższy\" vs \"pierwszy\"** - jest TYLKO JEDEN najdłuższy w pliku, więc nie ma niejasności.\n\n## Złożoność obliczeniowa\n\n- Jedno-przebiegowy algorytm: **O(n)** czasu, O(1) pamięci.\n- Dla 500 dni: ~500 operacji.\n- Z parsowaniem CSV: O(n · k), gdzie k = długość linii.","image":null,"solution_image":null,"topics":null,"page_from":null,"source":"maturazai","answer_source":null,"answer_text_source":null,"solution_source":"maturazai","text_source":"maturazai","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/5.3","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"5.3","points":3,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Kontekst - patrz zadanie 5.1.\n\nDla pierwszych 300 dni pomiaru oblicz, z dokładnością do dwóch miejsc po przecinku, średni opad dla każdego rodzaju chmur (kategoria + wielkość, czyli C1, C2, C3, C4, C5, S1, S2, S3, S4, S5). Przedstaw wyniki na wykresie kolumnowym, pamiętając o czytelnym opisie wykresu.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Średni opad dla każdego rodzaju chmur (pierwsze 300 dni):**\n\n| Rodzaj chmury | Średnie opady (mm) |\n| C1 | **3,45** |\n| C2 | **7,28** |\n| C3 | **9,05** |\n| C4 | **11,58** |\n| C5 | **19,40** |\n| S1 | **3,73** |\n| S2 | **6,52** |\n| S3 | **10,29** |\n| S4 | **15,00** |\n| S5 | **19,64** |\n\n**Obserwacje:**\n- Im większa chmura (1→5), tym większy średni opad.\n- Stratusy (S) lekko intensywniejsze niż cirrusy (C) - przy tej samej wielkości.\n- Największe opady dla C5 i S5 (~19-20 mm).\n\n## Sposób 1 - Python z agregacją (rekomendowane)\n\n```python\nfrom collections import defaultdict\nimport matplotlib.pyplot as plt\n\nsumy = defaultdict(float)\nlicznosc = defaultdict(int)\n\nwith open('pogoda.txt', encoding='utf-8') as f:\nf.readline() # nagłówek\nfor _ in range(300):\nlinia = f.readline().strip()\npola = linia.split(';')\nopad = int(pola[2])\nkategoria = pola[3]\nwielkosc = pola[4]\nif kategoria == '0' or wielkosc == '0':\ncontinue # pomijamy dni bezchmurne\nrodzaj = f'{kategoria}{wielkosc}'\nsumy[rodzaj] += opad\nlicznosc[rodzaj] += 1\n\nrodzaje = ['C1','C2','C3','C4','C5','S1','S2','S3','S4','S5']\nsrednie = [round(sumy[r] / licznosc[r], 2) for r in rodzaje]\n\nfor r, s in zip(rodzaje, srednie):\nprint(f'{r}: {s}')\n\n# Wykres kolumnowy\nplt.figure(figsize=(10,6))\nkolory = ['#4488dd']*5 + ['#dd4488']*5\nplt.bar(rodzaje, srednie, color=kolory)\nplt.title('Średni opad dla każdego rodzaju chmur (pierwsze 300 dni)')\nplt.xlabel('Rodzaj chmury (kategoria + wielkość)')\nplt.ylabel('Średni opad [mm]')\nplt.grid(axis='y', alpha=0.3)\nfor i, v in enumerate(srednie):\nplt.text(i, v + 0.3, f'{v:.2f}', ha='center', fontsize=10)\nplt.tight_layout()\nplt.savefig('wykres_chmury.png', dpi=100)\nplt.show()\n\n## Sposób 2 - arkusz kalkulacyjny\n\n**Krok 1: utwórz kolumnę pomocniczą F (rodzaj chmur).**\nF2 = JEŻELI(D2=\"0\"; \"\"; D2 & E2)\nSkopiuj F3:F301 (pierwsze 300 dni).\n\n**Krok 2: tabela średnich.**\nW komórkach G2:G11 wpisz nazwy: C1, C2, , S5.\nW H2 (średni opad dla C1):\n=ZAOKR(ŚREDNIA.JEŻELI(F2:F301; G2; C2:C301); 2)\nSkopiuj H2:H11.\n\n**Krok 3: wykres kolumnowy.**\nZaznacz G1:H11 → Wstaw → Wykres → Kolumnowy.\nDodaj tytuł \"Średnie opady dla rodzajów chmur (dni 1-300)\", osie: X = \"Rodzaj chmury\", Y = \"Opad [mm]\".\n\n## Sposób 3 - SQL\n\n```sql\nSELECT\nKategoria_chmur || Wielkosc_chmur AS Rodzaj,\nROUND(AVG(Opad), 2) AS Sredni_opad\nFROM pogoda\nWHERE Dzien <= 300 AND Kategoria_chmur <> '0'\nGROUP BY Kategoria_chmur, Wielkosc_chmur\nORDER BY Rodzaj;\n\n## Reference informatyczny - agregacja danych i wykres kolumnowy\n\n> Reference - Agregacja:\n> - **GROUP BY** w SQL, **ŚREDNIA.JEŻELI** w arkuszu, **defaultdict** w Python.\n> - **ZAOKR(x, n)** zaokrągla do n miejsc po przecinku.\n>\n> Reference - Wykres kolumnowy:\n> - Oś X: kategorie (rodzaje chmur).\n> - Oś Y: wartość liczbowa (średnia).\n> - **Wymagania CKE:**\n> - Tytuł wykresu.\n> - Opis osi X i Y (etykiety).\n> - Legenda jeśli kilka serii.\n> - Czytelność (kolory, font).\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 5.3, max 3 pkt):\n> - **1 pkt** - prawidłowe wyniki w zestawieniu danych\n> - **1 pkt** - odpowiednia dokładność (2 miejsca po przecinku)\n> - **1 pkt** - prawidłowy wykres (kolumnowy + opisy)\n> - **0 pkt** - błędna lub brak\n>\n> **Uwaga:** zestawienie dla 500 dni zamiast 300 → max 2 pkt.\n\n## Typowe pułapki\n\n- **Liczenie wszystkich 500 dni zamiast pierwszych 300** - wynika z pominięcia warunku `Dzien <= 300`.\n- **Włączenie dni bezchmurnych (\"00\")** - treść mówi o RODZAJACH chmur, więc 0 (brak chmur) NIE jest jednym z rodzajów.\n- **Złe zaokrąglenie** - `round()` w Python z bankers rounding (ROUND_HALF_EVEN) różni się czasem od standardowego.\n- **Brak opisów osi/tytułu** - w CKE wykres BEZ opisu = 0 punktów za wykres.\n- **Wykres słupkowy zamiast kolumnowego** - \"słupkowy\" (poziome słupki) vs \"kolumnowy\" (pionowe kolumny).\n\n## Złożoność obliczeniowa\n\n- Czytanie 300 wierszy: O(n).\n- Agregacja per rodzaj (max 10 kategorii): O(n).\n- Generowanie wykresu: O(k) gdzie k = 10 słupków.\n- **Łącznie: O(n) ≈ 300 operacji**.","image":null,"solution_image":null,"topics":null,"page_from":null,"source":"maturazai","answer_source":null,"answer_text_source":null,"solution_source":"maturazai","text_source":"maturazai","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/5.4","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"5.4","points":4,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Kontekst - patrz zadanie 5.1.\n\nProfesor George Nubis przedstawił teorię, według której chmury określonej wielkości i kategorii rozwijają się w następujący sposób:\n- jeśli w danym dniu nie ma chmur, nazajutrz na pewno pojawią się chmury o wielkości 1,\n- chmury po trzech dniach samoczynnie przechodzą w chmury o wyższym numerze, aż do numeru 5,\n- chmury o wielkości 5 zanikają wtedy, gdy spadnie w ciągu dnia co najmniej 20 mm deszczu, a wówczas następny dzień jest bezchmurny,\n- powstanie chmur kategorii C lub S zależy od temperatury powietrza w dniu ich tworzenia się. Jeśli temperatura w dniu pojawienia się chmur jest nie mniejsza niż 10 stopni, to powstają chmury kategorii C (o wielkości 1), w przeciwnym wypadku - chmury kategorii S (o wielkości 1).\n\nUwaga: Przez pierwszych 20 dni teoria zgodziła się dokładnie z obserwacjami. Użyj tej informacji, aby sprawdzić swoje obliczenia.\n\nZałóż, że chmury rozwijałyby się przez cały czas (500 dni) według teorii profesora i że dzień pierwszy był bezchmurny (wielkość chmur 0), a następnie:\n\na) podaj liczbę dni (spośród wszystkich 500) z chmurami wielkości 0, 1, 2, 3, 4 i 5 - dla każdej wielkości oddzielnie (przyjmij, że wielkość opadu w danym dniu jest taka, jaką zapisano w pliku z danymi),\n\nb) dla pierwszych 300 dni pomiaru podaj, ile wśród nich było takich, w których teorię profesora Nubisa dotyczącą wielkości chmur potwierdzały odczyty z kamery,\n\nc) dla pierwszych 300 dni pomiaru podaj, ile wśród nich było takich, w których teorię profesora Nubisa dotyczącą kategorii chmur potwierdzały odczyty z kamery.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**a) Liczba dni z chmurami każdej wielkości (500 dni, teoria prof. Nubisa):**\n\n| Wielkość | Liczba dni |\n| 0 | **34** |\n| 1 | **102** |\n| 2 | **102** |\n| 3 | **102** |\n| 4 | **100** |\n| 5 | **60** |\n\n**b) Liczba dni z pierwszych 300, gdzie teoria potwierdza WIELKOŚĆ chmur: 296**\n\n**c) Liczba dni z pierwszych 300, gdzie teoria potwierdza KATEGORIĘ chmur (C/S): 286**\n\n## Sposób 1 - symulacja w Python\n\n**Reguły teorii profesora Nubisa:**\n1. Dzień 1: bezchmurnie (wielkość = 0).\n2. Jeśli wczoraj nie było chmur → dziś wielkość = 1.\n3. Chmury \"żyją\" 3 dni na danej wielkości, potem przechodzą o jeden wyżej (do max 5).\n4. Chmury 5 zanikają (→ 0) gdy spadnie ≥ 20 mm w danym dniu.\n5. Kategoria (C/S): zależy od temperatury w dniu pojawienia się chmur:\n- temp ≥ 10°C → cirrus (C)\n- temp < 10°C → stratus (S)\n- Kategoria UTRZYMUJE SIĘ przez cały okres istnienia chmur.\n\n```python\n# Wczytaj dane\ndni = [] # (dzien, temp, opad, kat_obs, wiel_obs)\nwith open('pogoda.txt', encoding='utf-8') as f:\nf.readline()\nfor linia in f:\npola = linia.strip().split(';')\ndni.append({\n'dzien': int(pola[0]),\n'temp': float(pola[1].replace(',', '.')),\n'opad': int(pola[2]),\n'kat_obs': pola[3],\n'wiel_obs': int(pola[4]) if pola[4].isdigit() else 0,\n})\n\n# Symulacja teorii profesora\nteoria_wiel = [] # wielkość chmur każdego dnia wg teorii\nteoria_kat = [] # kategoria chmur (C/S/0)\nwielkosc = 0 # dzień 1 - bezchmurny\nkategoria = '0'\ndni_na_wielkosci = 0 # licznik dni na obecnej wielkości\n\nfor i, d in enumerate(dni):\nif i == 0:\n# dzień 1: bezchmurnie\nteoria_wiel.append(0)\nteoria_kat.append('0')\ncontinue\n# Reguły ewolucji (na podstawie poprzedniego dnia):\npoprzedni_w = teoria_wiel[i-1]\npoprzedni_k = teoria_kat[i-1]\npoprzedni_opad = dni[i-1]['opad']\nif poprzedni_w == 0:\n# wczoraj bezchmurne - dziś wielkość 1, kategoria wg dzisiejszej temp\nnowa_w = 1\nnowa_k = 'C' if d['temp'] >= 10 else 'S'\ndni_na_wielkosci = 1\nelif poprzedni_w == 5 and poprzedni_opad >= 20:\n# opadało ≥20mm → dziś bezchmurnie\nnowa_w = 0\nnowa_k = '0'\ndni_na_wielkosci = 0\nelse:\n# kontynuacja: jeśli na obecnej wielkości jest już 3. dzień → następna wielkość\nif dni_na_wielkosci >= 3 and poprzedni_w < 5:\nnowa_w = poprzedni_w + 1\ndni_na_wielkosci = 1\nelse:\nnowa_w = poprzedni_w\ndni_na_wielkosci += 1\nnowa_k = poprzedni_k\nteoria_wiel.append(nowa_w)\nteoria_kat.append(nowa_k)\n\n# a) zliczenia\nfrom collections import Counter\nprint('a)', Counter(teoria_wiel))\n# Counter({1: 102, 2: 102, 3: 102, 4: 100, 5: 60, 0: 34})\n\n# b) dni z pierwszych 300, gdzie wielkość zgadza się z obserwacją\nzgodne_w = sum(1 for i in range(300) if teoria_wiel[i] == dni[i]['wiel_obs'])\nprint('b)', zgodne_w) # 296\n\n# c) dni z pierwszych 300, gdzie kategoria zgadza się z obserwacją\nzgodne_k = sum(1 for i in range(300) if teoria_kat[i] == dni[i]['kat_obs'])\nprint('c)', zgodne_k) # 286\n\n## Sposób 2 - alternatywa: arkusz kalkulacyjny\n\nW arkuszu dodaj kolumny pomocnicze:\n- **G (wielkość teoretyczna)** - formuła z `JEŻELI` na podstawie G poprzedniego dnia i opadu.\n- **H (kategoria teoretyczna)** - `JEŻELI(G_wczoraj=0; JEŻELI(B_dziś≥10; \"C\"; \"S\"); H_wczoraj)`.\n- **I (zgodność wielkości)** - `JEŻELI(G_dziś=E_dziś; 1; 0)`.\n- **J (zgodność kategorii)** - `JEŻELI(H_dziś=D_dziś; 1; 0)`.\n\nNastępnie:\n- `LICZ.JEŻELI(G2:G501; 0)` daje liczbę dni z wielkością 0, itd.\n- `SUMA(I2:I301)` daje punkt b).\n- `SUMA(J2:J301)` daje punkt c).\n\n## Reference informatyczny - symulacja state machine\n\n> Reference - Symulacja \"automatu stanowego\":\n> - Stan: (wielkość, kategoria, dni_na_wielkosci).\n> - Przejścia: deterministyczne reguły na podstawie poprzedniego stanu + dane środowiskowe (temp, opad).\n> - Implementacja iteracyjna: tabela kolejnych stanów dni.\n> - Złożoność: O(n) - n = 500 dni.\n>\n> Reference - Walidacja teorii vs obserwacja:\n> - Porównaj predykcję (teoria) z obserwacją (dane z kamery) per dzień.\n> - Licznik zgodności = ile dni pasuje.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 5.4, max 4 pkt):\n> - **2 pkt** - zestawienie a) (lub 1 pkt jeśli max 2 błędne wartości)\n> - **1 pkt** - odpowiedź b) (296)\n> - **1 pkt** - odpowiedź c) (286)\n> - **0 pkt** - błędna albo brak\n\n## Typowe pułapki\n\n- **Pomylenie reguły \"3 dni\"** - chmura przechodzi PO 3 dniach (4. dzień to nowa wielkość), NIE w trakcie 3 dni.\n- **Brak warunku \"opad ≥ 20\" dla rozpadu 5 → 0** - chmury 5 nie znikają same, potrzebują deszczu.\n- **Kategoria zmienia się każdego dnia** - BŁĄD! Kategoria ustala się przy POWSTANIU chmur (wielkość 1) i utrzymuje przez całą \"żywotność\".\n- **Temperatura dnia tworzenia (wielkość 1)** - używamy temp tego dnia, NIE poprzedniego.\n- **Liczenie 500 dni dla b) i c)** - pytanie wyraźnie mówi o pierwszych 300.\n- **Pierwszy dzień bezchmurny** - zaczynamy od stanu (0, brak kategorii).\n\n## Złożoność obliczeniowa\n\n- Symulacja: **O(n)** = O(500).\n- Porównanie z obserwacjami: O(n).\n- Pamięć: O(n) dla tabel stanów.\n- Łącznie ~1500 operacji - natychmiastowe.","image":null,"solution_image":null,"topics":null,"page_from":null,"source":"maturazai","answer_source":null,"answer_text_source":null,"solution_source":"maturazai","text_source":"maturazai","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/6.1","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"6.1","points":1,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Zadanie 6. Perfumeria DlaWas\n\nW plikach: marki.txt, perfumy.txt, sklad.txt opisana jest oferta perfumerii „DlaWas”. W perfumerii dostępne są perfumy różnych marek. Perfumy składają się z kilku składników. Zestaw składników decyduje, do jakiej rodziny zapachów należą perfumy.\nPierwszy wiersz w każdym z plików jest wierszem nagłówkowym i zawiera nazwy pól. Dane w każdym wierszu oddzielone są znakiem tabulacji.\n\n**marki.txt** - pola: id_marki (identyfikator marki), nazwa_m (nazwa marki).\nPrzykład:\nid_marki | nazwa_m\nm_1 | Mou De Rosine\nm_2 | Mou&Bob\n\n**perfumy.txt** - pola: id_perfum, nazwa_p, id_marki, rodzina_zapachow (nazwa rodziny zapachów), cena (cena perfum).\nPrzykład:\nid_perfum | nazwa_p | id_marki | rodzina_zapachow | cena\np_1 | Ythde | m_1 | orientalna | 241\np_2 | Ythsas | m_1 | kwiatowa | 738\n\n**sklad.txt** - pola: id_perfum, nazwa_skladnika.\nPrzykład:\nid_perfum | nazwa_skladnika\np_1 | chryzantema\np_1 | kwiat irysa\n\nZa pomocą dostępnych narzędzi informatycznych podaj odpowiedzi do poniższych zadań. Odpowiedzi zapisz w pliku wyniki6.txt, a każdą z nich poprzedź numerem odpowiedniego zadania.\n\nPodaj listę wszystkich nazw perfum, których jednym ze składników jest „absolut jasminu”.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Lista nazw perfum z \"absolut jasminu\" jako składnikiem:**\nOyal Priather\nOlogne D'oud\nUelques FleuE\n\n(Dokładnie 3 perfumy. Nazwy zgodne z kluczem CKE - pochodzą z plików dostarczonych w arkuszu.)\n\n## Sposób 1 - SQL (najprostsze rozwiązanie)\n\n```sql\nSELECT DISTINCT p.nazwa_p\nFROM perfumy p\nINNER JOIN sklad s ON p.id_perfum = s.id_perfum\nWHERE s.nazwa_skladnika = 'absolut jasminu';\n\n## Sposób 2 - Python\n\n```python\n# Wczytaj składniki\nperfumy_z_jasminem = set()\nwith open('sklad.txt', encoding='utf-8') as f:\nf.readline() # nagłówek\nfor linia in f:\nid_perfum, nazwa_skl = linia.strip().split('\\t')\nif nazwa_skl == 'absolut jasminu':\nperfumy_z_jasminem.add(id_perfum)\n\n# Znajdź nazwy perfum\nwynik = []\nwith open('perfumy.txt', encoding='utf-8') as f:\nf.readline()\nfor linia in f:\npola = linia.strip().split('\\t')\nid_p, nazwa, id_m, rodzina, cena = pola\nif id_p in perfumy_z_jasminem:\nwynik.append(nazwa)\n\nfor n in wynik:\nprint(n)\n\n## Sposób 3 - arkusz kalkulacyjny\n\n**Krok 1:** w pliku sklad.txt filtruj `nazwa_skladnika = \"absolut jasminu\"` → otrzymasz listę id_perfum.\n\n**Krok 2:** WYSZUKAJ.PIONOWO każdego id_perfum w perfumy.txt aby uzyskać nazwa_p.\n\nLub jedna formuła (jeśli sklad.txt ma id_perfum w A, nazwa w B):\n=WYSZUKAJ.PIONOWO(A2; perfumy.txt!A:B; 2; 0)\nDla każdego wiersza gdzie B = \"absolut jasminu\".\n\nAlternatywnie tabela przestawna z filtrowaniem po nazwa_skladnika.\n\n## Reference informatyczny - JOIN z filtrem\n\n> Reference - INNER JOIN w SQL:\n> - Łączy wiersze z dwóch tabel po wspólnym kluczu.\n> - Tylko wiersze, które pasują w obu tabelach.\n> - `ON p.id_perfum = s.id_perfum` - warunek złączenia.\n>\n> Reference - DISTINCT:\n> - Usuwa duplikaty z wyniku.\n> - Tutaj nie ma duplikatów (każdy id_perfum występuje raz w perfumy.txt), ale dla pewności.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 6.1, max 1 pkt):\n> - **1 pkt** - pełna poprawna odpowiedź (3 nazwy)\n> - **0 pkt** - błędna lub brak\n\n## Typowe pułapki\n\n- **Wyszukiwanie po `LIKE '%jasmin%'` zamiast `= 'absolut jasminu'`** - może dać dodatkowe składniki typu \"olejek jasminowy\".\n- **Polskie znaki** - \"jasminu\" vs \"jaśminu\" - sprawdź dokładną pisownię w danych.\n- **JOIN po złym kluczu** - id_perfum vs id_marki.\n- **Pominięcie tabeli sklad.txt** - bez niej nie ma jak znaleźć perfum po składniku.\n\n## Złożoność obliczeniowa\n\n- SQL z indeksem na nazwa_skladnika: **O(log n)** dla wyszukiwania + O(k) dla join, k = wynikowe wiersze.\n- Bez indeksów: O(n × m).\n- Pamięć: O(k) dla zbioru id_perfum.","image":null,"solution_image":null,"topics":null,"page_from":null,"source":"maturazai","answer_source":null,"answer_text_source":null,"solution_source":"maturazai","text_source":"maturazai","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/6.2","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"6.2","points":3,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Kontekst - patrz zadanie 6.1.\n\nPodaj listę różnych rodzin zapachów. Dla każdej rodziny podaj jej nazwę, cenę najtańszych perfum z tej rodziny i ich nazwę.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**18 rodzin zapachów z najtańszymi perfumami:**\n\n| Rodzina zapachów | Cena | Nazwa |\n| aromatyczna | 124 | Ibrary Ollec D'amore |\n| cytrusowa | 259 | Sian Grad |\n| cytrusowo-aromatyczna | 178 | Re Nostrum,ir |\n| drzewna | 123 | Pperlee Bouquet |\n| kwiatowa | 110 | Ose Deurmaline |\n| kwiatowo-drzewna | 104 | Rougna |\n| kwiatowo-orientalna | 103 | Arla : Vivace |\n| kwiatowo-szyprowa | 287 | Etish Pothal |\n| orientalna | 113 | Anille La Tosca |\n| orientalna lagodna | 122 | Ndy Warhol S Rose |\n| orientalno-drzewna | 138 | LackNight |\n| owocowa | 154 | Ake Perfucturne |\n| pudrowa | 139 | Ivm Cristal |\n| skorzana | 112 | Ui Mare |\n| szyprowa | 226 | Usk ti 1888 |\n| szyprowo-skorzana | 158 | Uir OtPlace |\n| wodna | 146 | Ilver Mounaya |\n| zielona | 406 | EOman |\n\n## Sposób 1 - SQL z podzapytaniem (najtańsze per rodzina)\n\n```sql\nSELECT p.rodzina_zapachow, p.cena, p.nazwa_p\nFROM perfumy p\nINNER JOIN (\nSELECT rodzina_zapachow, MIN(cena) AS min_cena\nFROM perfumy\nGROUP BY rodzina_zapachow\n) m ON p.rodzina_zapachow = m.rodzina_zapachow AND p.cena = m.min_cena\nORDER BY p.rodzina_zapachow;\n\n**Wyjaśnienie:** Podzapytanie znajduje najniższą cenę per rodzina. JOIN z tabelą perfumy daje też nazwę produktu o tej cenie.\n\n## Sposób 2 - Python z agregacją\n\n```python\nfrom collections import defaultdict\n\nnajtansze = {} # rodzina -> (cena, nazwa)\n\nwith open('perfumy.txt', encoding='utf-8') as f:\nf.readline()\nfor linia in f:\npola = linia.strip().split('\\t')\nid_p, nazwa, id_m, rodzina, cena = pola\ncena = int(cena)\nif rodzina not in najtansze or cena < najtansze[rodzina][0]:\nnajtansze[rodzina] = (cena, nazwa)\n\nfor rodzina in sorted(najtansze):\ncena, nazwa = najtansze[rodzina]\nprint(f'{rodzina:30} {cena:5} {nazwa}')\n\n## Sposób 3 - arkusz kalkulacyjny (tabela przestawna)\n\n**Wariant 1 (tabela przestawna):**\n1. Wstaw → Tabela przestawna.\n2. Wiersze: `rodzina_zapachow`.\n3. Wartości: `cena` z funkcją MIN.\n\nTo daje rodzinę + minimalną cenę. Aby uzyskać nazwę produktu - INDEX/MATCH:\n\n=INDEKS(perfumy!B:B; PODAJ.POZYCJĘ(1; (perfumy!D:D=A2)*(perfumy!E:E=B2); 0))\n(formuła tablicowa, Ctrl+Shift+Enter)\n\n## Reference informatyczny - GROUP BY z dodatkowymi kolumnami\n\n> Reference - Typowy problem \"min/max group_by z innym polem\":\n> - SQL standard: GROUP BY zwraca tylko grupę + agregat. Aby dodać inną kolumnę (np. nazwa_p), potrzebujemy podzapytania lub window function.\n> - Podzapytanie: `JOIN (SELECT rodzina, MIN(cena) FROM perfumy GROUP BY rodzina) ON `.\n> - Window function (nowoczesny SQL): `ROW_NUMBER() OVER (PARTITION BY rodzina ORDER BY cena ASC) = 1`.\n> - Python defaultdict z iteracyjnym update - najwygodniej.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 6.2, max 3 pkt):\n> - **1 pkt** - prawidłowa lista 18 rodzin zapachów\n> - **1 pkt** - cena najtańszych perfum dla każdej rodziny\n> - **1 pkt** - nazwa najtańszych perfum dla każdej rodziny\n> - **0 pkt** - błędna lub brak\n\n## Typowe pułapki\n\n- **`SELECT rodzina, MIN(cena), nazwa_p`** - bez podzapytania! W standardowym SQL to BŁĄD (nazwa_p nie jest w GROUP BY i nie jest agregatem).\n- **Brak DISTINCT** - duplikaty rodzin jeśli ta sama rodzina ma kilka perfum o tej samej minimalnej cenie.\n- **Sortowanie** - nie jest wymagane przez treść, ale ułatwia czytanie.\n- **Pomylenie kolumn** - w perfumy.txt: id_perfum, nazwa_p, id_marki, rodzina_zapachow, cena.\n\n## Złożoność obliczeniowa\n\n- SQL z indeksem na rodzina_zapachow: O(n log n) sortowanie + O(n) join.\n- Python defaultdict: O(n) - n = liczba perfum.\n- Wynik: 18 rodzin (z danych).","image":null,"solution_image":null,"topics":null,"page_from":null,"source":"maturazai","answer_source":null,"answer_text_source":null,"solution_source":"maturazai","text_source":"maturazai","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/6.3","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"6.3","points":3,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Kontekst - patrz zadanie 6.1.\n\nUtwórz uporządkowaną alfabetycznie listę wszystkich nazw marek, które nie zawierają w swoich perfumach żadnego składnika mającego w nazwie słowo „paczula”.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Marki bez \"paczuli\" wśród składników (alfabetycznie):**\nAison Eranciro\nArthbey\nEmbert Lucas\nEnmith\nNnick a Kieffo\n\n## Sposób 1 - SQL z NOT EXISTS\n\n```sql\nSELECT m.nazwa_m\nFROM marki m\nWHERE NOT EXISTS (\nSELECT 1\nFROM perfumy p\nINNER JOIN sklad s ON p.id_perfum = s.id_perfum\nWHERE p.id_marki = m.id_marki\nAND s.nazwa_skladnika LIKE '%paczula%'\n)\nORDER BY m.nazwa_m;\n\n**Wyjaśnienie:**\n- Główne zapytanie: marki.\n- Podzapytanie: czy marka ma jakiś składnik z \"paczula\" w nazwie?\n- `NOT EXISTS`: zwróć marki, które **nie mają** takiego składnika.\n- `LIKE '%paczula%'`: \"paczula\" gdziekolwiek w nazwie (np. \"paczula indonezyjska\", \"olejek z paczuli\").\n- `ORDER BY`: sortowanie alfabetyczne.\n\n## Sposób 2 - SQL alternatywne (LEFT JOIN + WHERE NULL)\n\n```sql\nSELECT DISTINCT m.nazwa_m\nFROM marki m\nWHERE m.id_marki NOT IN (\nSELECT DISTINCT p.id_marki\nFROM perfumy p\nINNER JOIN sklad s ON p.id_perfum = s.id_perfum\nWHERE s.nazwa_skladnika LIKE '%paczula%'\n)\nORDER BY m.nazwa_m;\n\n## Sposób 3 - Python\n\n```python\n# Wczytaj marki: id -> nazwa\nmarki = {}\nwith open('marki.txt', encoding='utf-8') as f:\nf.readline()\nfor linia in f:\nid_m, nazwa = linia.strip().split('\\t')\nmarki[id_m] = nazwa\n\n# Wczytaj perfumy: id_perfum -> id_marki\nperf_marka = {}\nwith open('perfumy.txt', encoding='utf-8') as f:\nf.readline()\nfor linia in f:\npola = linia.strip().split('\\t')\nperf_marka[pola[0]] = pola[2]\n\n# Znajdź marki, które mają składnik z \"paczula\"\nmarki_z_paczula = set()\nwith open('sklad.txt', encoding='utf-8') as f:\nf.readline()\nfor linia in f:\nid_p, nazwa_skl = linia.strip().split('\\t')\nif 'paczula' in nazwa_skl.lower():\nid_m = perf_marka.get(id_p)\nif id_m:\nmarki_z_paczula.add(id_m)\n\n# Marki BEZ paczuli\nwynik = sorted([marki[id_m] for id_m in marki if id_m not in marki_z_paczula])\nfor m in wynik:\nprint(m)\n\n## Sposób 4 - arkusz kalkulacyjny\n\n**Krok 1:** w sklad.txt - kolumna pomocnicza C: `=JEŻELI(ISNUMBER(SZUKAJ.TEKST(\"paczula\"; B2)); A2; \"\")`. To daje id_perfum jeśli składnik zawiera paczulę.\n\n**Krok 2:** zbierz unikalne id_perfum (zaawansowany filtr lub UNIQUE).\n\n**Krok 3:** dopasuj id_perfum → id_marki (VLOOKUP w perfumy.txt).\n\n**Krok 4:** lista wszystkich marek minus te z paczulą - formuła `IF(COUNTIF(zlepaczula; id_marki) = 0; nazwa; \"\")`.\n\n**Krok 5:** sortuj alfabetycznie.\n\n## Reference informatyczny - NOT EXISTS vs NOT IN\n\n> Reference - Subqueries z negacją:\n> - `NOT EXISTS (SELECT WHERE )`: efektywne, działa poprawnie z NULL.\n> - `NOT IN (SELECT )`: prostsze, ale ma pułapkę - jeśli podzapytanie zwróci NULL, cały warunek staje się UNKNOWN (faktycznie FALSE)!\n> - **Preferowane: `NOT EXISTS`** - bezpieczniejsze.\n>\n> Reference - LIKE z wildcardami:\n> - `%paczula%` - \"paczula\" gdziekolwiek (start, środek, koniec).\n> - `paczula%` - zaczyna od \"paczula\".\n> - `%paczula` - kończy na \"paczula\".\n> - `_paczula_` - z dokładnie jednym znakiem przed i po.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 6.3, max 3 pkt):\n> - **2 pkt** - zastosowanie filtra `*paczula*` (= `%paczula%`)\n> - **1 pkt** - filtr `paczula*` lub samo `paczula` (zamiast `*paczula*`) - niepełne\n> - **1 pkt** - sortowanie alfabetyczne\n> - **0 pkt** - błędna lub brak\n\n## Typowe pułapki\n\n- **`= 'paczula'`** zamiast `LIKE '%paczula%'` - pominie składniki typu \"olejek paczuli\".\n- **`paczula%`** - pominie składniki typu \"olejek paczuli\" (nie zaczyna się od paczula).\n- **Pomylenie polskich znaków** - \"paczula\" (litera 'l') vs \"paczuli\" (l, ale forma deklinacyjna).\n- **Brak sortowania** - utrata 1 punktu.\n- **`NOT IN` z NULL** - może spowodować błędy. Lepiej `NOT EXISTS`.\n- **Pomylenie kierunku** - listujemy marki BEZ paczuli, NIE marki Z paczulą.\n\n## Złożoność obliczeniowa\n\n- SQL z indeksami: O(n log n) sortowanie + O(n + m) join.\n- Python: O(n + m) - dwa przejścia przez pliki.\n- Pamięć: O(liczba marek + liczba składników z paczulą).","image":null,"solution_image":null,"topics":null,"page_from":null,"source":"maturazai","answer_source":null,"answer_text_source":null,"solution_source":"maturazai","text_source":"maturazai","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/6.4","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"6.4","points":3,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Kontekst - patrz zadanie 6.1.\n\nCeny wszystkich perfum marki Mou De Rosine z rodziny o nazwie „orientalno-drzewna” zostały obniżone o 15%. Podaj listę zawierającą wszystkie nazwy takich perfum i ich ceny po obniżce. Listę posortuj niemalejąco według ceny.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Perfumy marki Mou De Rosine z rodziny \"orientalno-drzewna\" po obniżce o 15%, posortowane niemalejąco:**\n\n| Nazwa | Nowa cena |\n| Ourn Boise | 141,95 |\n| Onou Back | 222,70 |\n| Pic An | 230,35 |\n| Nterl Bambola | 292,40 |\n| Ubilatio Champs | 381,65 |\n| Ibrary Ollec D'or | 489,60 |\n| Ate An | 544,85 |\n| Elov & Musc | 660,45 |\n\n8 perfum spełniających dwa warunki (marka = Mou De Rosine + rodzina = orientalno-drzewna). Cena po obniżce = cena_oryginalna × 0,85.\n\n## Sposób 1 - SQL (JOIN + filtr + obniżka)\n\n```sql\nSELECT p.nazwa_p, ROUND(p.cena * 0.85, 2) AS nowa_cena\nFROM perfumy p\nINNER JOIN marki m ON p.id_marki = m.id_marki\nWHERE m.nazwa_m = 'Mou De Rosine'\nAND p.rodzina_zapachow = 'orientalno-drzewna'\nORDER BY nowa_cena ASC;\n\n**Wynik:**\nOurn Boise 141.95\nOnou Back 222.70\nPic An 230.35\nNterl Bambola 292.40\nUbilatio Champs 381.65\nIbrary Ollec D'or 489.60\nAte An 544.85\nElov & Musc 660.45\n\n## Sposób 2 - Python\n\n```python\n# Wczytaj marki: nazwa -> id\nmarki = {}\nwith open('marki.txt', encoding='utf-8') as f:\nf.readline() # naglowek\nfor linia in f:\nidm, nazwa = linia.strip().split('\\t')\nmarki[nazwa] = idm\n\nid_mou = marki['Mou De Rosine']\n\n# Wczytaj perfumy, filtruj, oblicz nowa cena\nwynik = []\nwith open('perfumy.txt', encoding='utf-8') as f:\nf.readline()\nfor linia in f:\nidp, nazwa, idm, rodzina, cena = linia.strip().split('\\t')\nif idm == id_mou and rodzina == 'orientalno-drzewna':\nnowa = round(int(cena) * 0.85, 2)\nwynik.append((nazwa, nowa))\n\n# Sortuj niemalejaco po cenie\nwynik.sort(key=lambda x: x[1])\nfor nazwa, cena in wynik:\nprint(f'{nazwa:25} {cena}')\n\n## Sposób 3 - arkusz kalkulacyjny\n\n**Krok 1:** Zaimportuj 3 pliki. W kolumnie pomocniczej w perfumy.txt dodaj nazwę marki przez WYSZUKAJ.PIONOWO po id_marki.\n\n**Krok 2:** Filtruj:\n- nazwa_m = \"Mou De Rosine\"\n- rodzina_zapachow = \"orientalno-drzewna\"\n\n**Krok 3:** Dodaj kolumnę nowa_cena: `=cena * 0,85` (lub formuła `=ROUND(cena*0,85; 2)`).\n\n**Krok 4:** Sortuj rosnąco po nowa_cena.\n\n## Reference algorytmiczny - JOIN + filtr + obniżka\n\n> Reference - Procentowa obniżka ceny:\n> - Obniżka o p% → mnoż przez (100 - p)/100, tzn. obniżka 15% → mnoż przez 0,85.\n> - **NIE** dodawaj obniżki do ceny (zwiększyłbyś cenę).\n> - **NIE** odejmuj 15 od ceny (15 zł zamiast 15% - błąd zaokrąglenia jednostki).\n> - Zaokrąglenie do 2 miejsc dziesiętnych obowiązkowe (kasowy standard).\n>\n> Reference - Dwa filtry:\n> - `WHERE a AND b` (oba warunki muszą być prawdziwe).\n> - W Pythonie/Pascal: `if a and b: `.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 6.4, max 3 pkt):\n> - **3 pkt** - pełna prawidłowa odpowiedź (8 perfum, ceny po obniżce, sortowane niemalejąco).\n> - **2 pkt** - prawidłowo posortowana lista z poprawnymi cenami, ale bez jednego z kryteriów filtrowania (np. tylko marka LUB tylko rodzina).\n> - **2 pkt** - poprawna lista bez sortowania.\n> - **1 pkt** - lista z poprawnie obliczonymi cenami (ale błąd w filtrowaniu lub sortowaniu).\n> - **0 pkt** - błędna lub brak.\n\n## Typowe pułapki\n\n- **Mnożenie przez 0,15 zamiast 0,85** - daje wartość obniżki, NIE cenę po obniżce. Częsta pomyłka.\n- **Odejmowanie 15** zamiast mnożenia × 0,85 - błąd jednostki (procent vs liczba).\n- **Brak JOIN z marki** - zadanie wymaga nazwy marki, w perfumy.txt jest tylko id_marki. Filtrowanie po `nazwa_m = 'Mou De Rosine'` wymaga JOIN.\n- **Sortowanie ASC vs DESC** - \"niemalejąco\" = ASC (rosnąco). Niemalejąco oznacza, że kolejne wartości są ≥ poprzedniej.\n- **Zaokrąglenie do 2 miejsc** - klucz CKE pokazuje 141,95 (nie 141 czy 141,9523). ROUND(x, 2) obowiązkowy.\n- **Polskie znaki w nazwach** - \"Mou De Rosine\" musi być DOKŁADNIE jak w pliku (case-sensitive zwykle).\n- **Tylko jeden filtr** - częsty błąd 2 pkt zamiast 3 (filtruj BARDZO Mou De Rosine LUB tylko orientalno-drzewna).\n\n## Złożoność obliczeniowa\n\n- SQL z indeksami: O(N log N) sortowanie + O(N) filtrowanie.\n- Python: O(N + M) dwa przejścia + O(K log K) sortowanie, K = wynikowe wiersze.\n- **Całkowita: O(N log N)** dla typowej implementacji.","image":null,"solution_image":null,"topics":null,"page_from":null,"source":"maturazai","answer_source":null,"answer_text_source":null,"solution_source":"maturazai","text_source":"maturazai","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"},{"id":"informatyka-2019-maj-matura-rozszerzona/zad/6.5","paper_id":"informatyka-2019-maj-matura-rozszerzona","number":"6.5","points":2,"ptype":"open","subject":"informatyka","category":"matura","year":2019,"month":"maj","level":"rozszerzona","text":"Kontekst - patrz zadanie 6.1.\n\nIstnieją marki, których wszystkie perfumy należą do tylko jednej rodziny zapachów. Podaj listę wszystkich nazw takich marek. Lista powinna zawierać nazwy marek i nazwy odpowiednich rodzin zapachów.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Marki, których wszystkie perfumy należą do dokładnie jednej rodziny zapachów:**\n\n| Nazwa marki | Rodzina zapachów |\n| **Ightce** | aromatyczna |\n| **X ICologne** | orientalno-drzewna |\n| **Nnick a Kieffo** | orientalna |\n| **Enmith** | kwiatowo-orientalna |\n| **Issmkunstwerke** | orientalna |\n\nIstnieje 5 takich marek. Kluczowa interpretacja: marka może mieć WIELE perfum, ale wszystkie muszą mieć tę samą wartość `rodzina_zapachow`.\n\n## Sposób 1 - SQL (GROUP BY z HAVING COUNT DISTINCT = 1)\n\n```sql\nSELECT m.nazwa_m, MIN(p.rodzina_zapachow) AS rodzina\nFROM marki m\nINNER JOIN perfumy p ON m.id_marki = p.id_marki\nGROUP BY m.id_marki, m.nazwa_m\nHAVING COUNT(DISTINCT p.rodzina_zapachow) = 1;\n\n**Wyjaśnienie:**\n- Grupujemy perfumy po marce.\n- `COUNT(DISTINCT rodzina_zapachow) = 1` → marka ma tylko 1 unikalną rodzinę.\n- `MIN(rodzina_zapachow)` zwraca tę jedyną rodzinę (można też `MAX` - wynik ten sam, bo unikalna).\n\n**Wynik:**\nIghtce | aromatyczna\nX ICologne | orientalno-drzewna\nNnick a Kieffo | orientalna\nEnmith | kwiatowo-orientalna\nIssmkunstwerke | orientalna\n\n## Sposób 2 - Python (zbiory)\n\n```python\nfrom collections import defaultdict\n\n# Wczytaj marki: id -> nazwa\nmarki = {}\nwith open('marki.txt', encoding='utf-8') as f:\nf.readline() # naglowek\nfor linia in f:\nidm, nazwa = linia.strip().split('\\t')\nmarki[idm] = nazwa\n\n# Dla kazdej marki zbierz zbior rodzin\nrodziny_per_marka = defaultdict(set)\nwith open('perfumy.txt', encoding='utf-8') as f:\nf.readline()\nfor linia in f:\nidp, nazwa, idm, rodzina, cena = linia.strip().split('\\t')\nrodziny_per_marka[idm].add(rodzina)\n\n# Wybierz marki z dokladnie jedna rodzina\nfor idm, zbior in rodziny_per_marka.items():\nif len(zbior) == 1:\nrodzina = next(iter(zbior))\nprint(f'{marki[idm]:25} | {rodzina}')\n\n## Sposób 3 - arkusz kalkulacyjny (tabela przestawna)\n\n**Krok 1:** Wczytaj perfumy.txt. Dodaj kolumnę nazwa marki (WYSZUKAJ.PIONOWO po id_marki w marki.txt).\n\n**Krok 2:** Tabela przestawna:\n- Wiersze: `nazwa_m`\n- Wartości: `rodzina_zapachow` z funkcją LICZBA UNIKATOWYCH (lub LICZ.UNIKATOWE.WARTOŚCI).\n\n**Krok 3:** Filtruj wiersze, gdzie liczba unikalnych rodzin = 1.\n\n**Krok 4:** Dla pozostałych marek znajdź tę jedyną rodzinę: `=INDEKS( )` lub przez drugą tabelę przestawną.\n\n## Reference algorytmiczny - COUNT DISTINCT w HAVING\n\n> Reference - Filtr na zagregowanej unikalności:\n> - `COUNT(DISTINCT kol) = 1` → wszystkie wartości w grupie są identyczne.\n> - `HAVING` filtruje grupy PO agregacji (nie pojedyncze wiersze - to robi WHERE).\n> - W Pythonie: `len(set( )) == 1` lub porównanie pierwszej i ostatniej wartości po sortowaniu.\n> - **Zwracanie wartości grupowej:** `MIN(kol)` lub `MAX(kol)` dla unikalnej wartości - daje tę jedyną wartość.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 6.5, max 2 pkt):\n> - **2 pkt** - pełna prawidłowa odpowiedź: nazwy 5 marek i 5 odpowiednich rodzin zapachów.\n> - **1 pkt** - tylko prawidłowa lista 5 marek (bez rodzin).\n> - **1 pkt** - lista 3 lub 4 marek z 5 w parze z prawidłową nazwą rodziny zapachów.\n> - **0 pkt** - błędna lub brak.\n\n## Typowe pułapki\n\n- **`COUNT(rodzina_zapachow) = 1`** zamiast `COUNT(DISTINCT rodzina_zapachow) = 1` - to pierwsze daje marki z tylko JEDNYM perfumem (a my chcemy marki z wieloma perfumami, byle z tej samej rodziny).\n- **Pominięcie marki z 1 perfumem** - jeśli marka ma tylko 1 perfum, to oczywiście ma 1 rodzinę. Te marki też zaliczają się do wyniku.\n- **Brak JOIN z `marki`** - w perfumy.txt jest tylko id_marki, potrzebujemy nazwa_m.\n- **GROUP BY tylko po id_marki** - niektóre silniki SQL wymagają wszystkich kolumn z SELECT także w GROUP BY (poza agregatami). Dla pewności dodaj `m.nazwa_m` do GROUP BY.\n- **Pominięcie kolumny z rodziną** - utrata 1 pkt z 2.\n- **Marki nie mające w ogóle perfum** - INNER JOIN je odfiltruje, a to dobrze (marka bez perfum nie ma rodziny).\n\n## Złożoność obliczeniowa\n\n- SQL z GROUP BY + COUNT DISTINCT: O(N log N) dla sortowania per grupa.\n- Python z defaultdict set: O(N) jedno przejście + O(M) wybieranie marek.\n- **Całkowita: O(N + M)** liniowa.","image":null,"solution_image":null,"topics":null,"page_from":null,"source":"maturazai","answer_source":null,"answer_text_source":null,"solution_source":"maturazai","text_source":"maturazai","source_label":"Informatyka · Matura · maj 2019 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura"}]}