{"id":"informatyka-2016-maj-matura-rozszerzona/zad/5.1","paper_id":"informatyka-2016-maj-matura-rozszerzona","number":"5.1","points":2,"ptype":"open","subject":"informatyka","category":"matura","year":2016,"month":"maj","level":"rozszerzona","text":"Zadanie 5. Biblioteka podręczników\n\nZ biblioteki podręczników, wypożyczanych na cały rok akademicki, mogą korzystać studenci z miasteczka akademickiego i spoza miasteczka. Każdy student może wypożyczyć wiele różnych książek. W miasteczku studenci mieszkają w pokojach po kilka osób w jednym.\n\nDane są trzy pliki: studenci.txt, meldunek.txt, wypozyczenia.txt.\n\n**studenci.txt** - pesel, nazwisko, imie.\n**meldunek.txt** - pesel, id_pok.\n**wypozyczenia.txt** - lp, pesel, tytul.\n\nPodaj imię i nazwisko osoby, która wypożyczyła najwięcej podręczników. Wypisz tytuły wszystkich książek przez nią wypożyczonych.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Imię i nazwisko: KRZYSZTOF LEWANDOWSKI**\n\n**Tytuły książek (4):**\n- FLASH I PHP\n- JEZYKI PROGRAMOWANIA II\n- METODY NUMERYCZNE II\n- TEORIA GRAFOW\n\n## Sposób 1 - SQL\n\n**Krok 1: znajdź PESEL osoby z największą liczbą wypożyczeń:**\n\n```sql\nSELECT pesel, COUNT(*) AS liczba\nFROM wypozyczenia\nGROUP BY pesel\nORDER BY liczba DESC\nLIMIT 1;\n\n**Krok 2: imię i nazwisko + tytuły książek:**\n\n```sql\nSELECT s.imie, s.nazwisko, w.tytul\nFROM studenci s\nJOIN wypozyczenia w ON s.pesel = w.pesel\nWHERE s.pesel = (\nSELECT pesel\nFROM wypozyczenia\nGROUP BY pesel\nORDER BY COUNT(*) DESC\nLIMIT 1\n)\nORDER BY w.tytul;\n\n**Wynik:**\nKRZYSZTOF | LEWANDOWSKI | FLASH I PHP\nKRZYSZTOF | LEWANDOWSKI | JEZYKI PROGRAMOWANIA II\nKRZYSZTOF | LEWANDOWSKI | METODY NUMERYCZNE II\nKRZYSZTOF | LEWANDOWSKI | TEORIA GRAFOW\n\n## Sposób 2 - Python\n\n```python\nfrom collections import Counter\n\n# Wczytaj studentów\nstudenci = {} # pesel -> (imie, nazwisko)\nwith open('studenci.txt', encoding='windows-1250') as f:\nnext(f) # header\nfor linia in f:\ncz = linia.strip().split('\\t')\nif len(cz) >= 3:\npesel, nazwisko, imie = cz[0], cz[1], cz[2]\nstudenci[pesel] = (imie, nazwisko)\n\n# Wczytaj wypożyczenia\nwypozyczenia = [] # (pesel, tytul)\nwith open('wypozyczenia.txt', encoding='windows-1250') as f:\nnext(f)\nfor linia in f:\ncz = linia.strip().split('\\t')\nif len(cz) >= 3:\npesel, tytul = cz[1], cz[2]\nwypozyczenia.append((pesel, tytul))\n\n# Policz wypożyczenia per pesel\nlicznik = Counter(p for p, _ in wypozyczenia)\nnajwiekszy_pesel, ile = licznik.most_common(1)[0]\n\nimie, nazwisko = studenci[najwiekszy_pesel]\nprint(f\"{imie} {nazwisko} (wypożyczył {ile} książek)\")\nfor pesel, tytul in wypozyczenia:\nif pesel == najwiekszy_pesel:\nprint(f\" - {tytul}\")\n\n**Wynik:**\nKRZYSZTOF LEWANDOWSKI (wypożyczył 4 książek)\n- FLASH I PHP\n- JEZYKI PROGRAMOWANIA II\n- METODY NUMERYCZNE II\n- TEORIA GRAFOW\n\n## Sposób 3 - arkusz kalkulacyjny\n\n1. **Tabela przestawna**: zaimportuj wypozyczenia.txt. Pole PESEL → wiersze. Pole TYTUL → wartości (Licznik).\n2. Sortuj malejąco wg licznika. Pierwszy wiersz to PESEL z największą liczbą.\n3. **VLOOKUP** w studenci.txt po PESEL → imię, nazwisko.\n4. **Filtruj** wypozyczenia.txt wg tego PESEL → uzyskaj listę tytułów.\n\n## Reference informatyczny - SQL agregacja\n\n> Reference - Klauzule SQL do tego typu zadania:\n> - `GROUP BY` - grupuje rekordy wg pola; każda grupa to jedna linia wyniku.\n> - `COUNT(*)` - liczba rekordów w grupie.\n> - `ORDER BY DESC LIMIT 1` - wybiera grupę z największą liczbą.\n> - **Podzapytanie skorelowane** - pozwala odwołać się do wyniku w innej części.\n> - `JOIN ON` - łączy dwie tabele po kluczu.\n>\n> Reference - Alternatywa zamiast LIMIT 1 + ORDER BY (MAX):\n> ```sql\n> WHERE COUNT(*) = (SELECT MAX(c) FROM (SELECT COUNT(*) AS c FROM wypozyczenia GROUP BY pesel))\n> ```\n> Jest bezpieczniej gdy chcemy WSZYSTKICH osób z maksimum, nie tylko jednej.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 5.1, max 2 pkt):\n> - **2 pkt** - imię, nazwisko ORAZ wszystkie tytuły\n> - **1 pkt** - tylko imię i nazwisko ALBO tylko tytuły\n> - **0 pkt** - odpowiedź niepełna lub błędna\n\n## Typowe pułapki\n\n- **Nieuwzględnienie wszystkich tytułów** - może być pominięcie 1 z 4. Klucz wymaga **wszystkich**.\n- **PESEL jako liczba** - PESEL to 11 cyfr; w int może wystąpić overflow w niektórych językach. Lepiej traktować jako string.\n- **Kodowanie pliku** - pliki CKE zwykle w Windows-1250 (polskie znaki). W Pythonie: `encoding='windows-1250'` lub `'cp1250'`.\n- **Separator** - w plikach CKE często TAB; sprawdzić w pierwszej linii.\n- **Pomylenie wypożyczeń (lp, pesel, tytul) z meldunkiem (pesel, id_pok)** - meldunek nie ma tytułów, służy tylko do zameldowania w pokojach.\n\n## Złożoność obliczeniowa\n\n- Wczytanie plików: O(S + W) gdzie S = liczba studentów, W = liczba wypożyczeń.\n- Counter agregujący: O(W).\n- Wyszukanie max: O(unikalnych PESEL).\n- **Łącznie: O(S + W).**","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 2016 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura","text_html":"<p>Zadanie 5. Biblioteka podręczników</p>\n<p>Z biblioteki podręczników, wypożyczanych na cały rok akademicki, mogą korzystać studenci z miasteczka akademickiego i spoza miasteczka. Każdy student może wypożyczyć wiele różnych książek. W miasteczku studenci mieszkają w pokojach po kilka osób w jednym.</p>\n<p>Dane są trzy pliki: studenci.txt, meldunek.txt, wypozyczenia.txt.</p>\n<p><strong>studenci.txt</strong> - pesel, nazwisko, imie.<br><strong>meldunek.txt</strong> - pesel, id_pok.<br><strong>wypozyczenia.txt</strong> - lp, pesel, tytul.</p>\n<p>Podaj imię i nazwisko osoby, która wypożyczyła najwięcej podręczników. Wypisz tytuły wszystkich książek przez nią wypożyczonych.</p>","solutions":[{"source":"maturazai","label":"maturazai.pl (AI)","kind":"text","html":"<h4>Poprawna odpowiedź</h4>\n<p><strong>Imię i nazwisko: KRZYSZTOF LEWANDOWSKI</strong></p>\n<p><strong>Tytuły książek (4):</strong></p>\n<ul><li>FLASH I PHP</li><li>JEZYKI PROGRAMOWANIA II</li><li>METODY NUMERYCZNE II</li><li>TEORIA GRAFOW</li></ul>\n<h4>Sposób 1 - SQL</h4>\n<p><strong>Krok 1: znajdź PESEL osoby z największą liczbą wypożyczeń:</strong></p>\n<p>```sql<br>SELECT pesel, COUNT(*) AS liczba<br>FROM wypozyczenia<br>GROUP BY pesel<br>ORDER BY liczba DESC<br>LIMIT 1;</p>\n<p><strong>Krok 2: imię i nazwisko + tytuły książek:</strong></p>\n<p>```sql<br>SELECT s.imie, s.nazwisko, w.tytul<br>FROM studenci s<br>JOIN wypozyczenia w ON s.pesel = w.pesel<br>WHERE s.pesel = (<br>SELECT pesel<br>FROM wypozyczenia<br>GROUP BY pesel<br>ORDER BY COUNT(*) DESC<br>LIMIT 1<br>)<br>ORDER BY w.tytul;</p>\n<p><strong>Wynik:</strong><br>KRZYSZTOF | LEWANDOWSKI | FLASH I PHP<br>KRZYSZTOF | LEWANDOWSKI | JEZYKI PROGRAMOWANIA II<br>KRZYSZTOF | LEWANDOWSKI | METODY NUMERYCZNE II<br>KRZYSZTOF | LEWANDOWSKI | TEORIA GRAFOW</p>\n<h4>Sposób 2 - Python</h4>\n<p>```python<br>from collections import Counter</p>\n<h3>Wczytaj studentów</h3>\n<p>studenci = {} # pesel -&gt; (imie, nazwisko)<br>with open(&#x27;studenci.txt&#x27;, encoding=&#x27;windows-1250&#x27;) as f:<br>next(f) # header<br>for linia in f:<br>cz = linia.strip().split(&#x27;\\t&#x27;)<br>if len(cz) &gt;= 3:<br>pesel, nazwisko, imie = cz[0], cz[1], cz[2]<br>studenci[pesel] = (imie, nazwisko)</p>\n<h3>Wczytaj wypożyczenia</h3>\n<p>wypozyczenia = [] # (pesel, tytul)<br>with open(&#x27;wypozyczenia.txt&#x27;, encoding=&#x27;windows-1250&#x27;) as f:<br>next(f)<br>for linia in f:<br>cz = linia.strip().split(&#x27;\\t&#x27;)<br>if len(cz) &gt;= 3:<br>pesel, tytul = cz[1], cz[2]<br>wypozyczenia.append((pesel, tytul))</p>\n<h3>Policz wypożyczenia per pesel</h3>\n<p>licznik = Counter(p for p, _ in wypozyczenia)<br>najwiekszy_pesel, ile = licznik.most_common(1)[0]</p>\n<p>imie, nazwisko = studenci[najwiekszy_pesel]<br>print(f&quot;{imie} {nazwisko} (wypożyczył {ile} książek)&quot;)<br>for pesel, tytul in wypozyczenia:<br>if pesel == najwiekszy_pesel:<br>print(f&quot; - {tytul}&quot;)</p>\n<p><strong>Wynik:</strong><br>KRZYSZTOF LEWANDOWSKI (wypożyczył 4 książek)</p>\n<ul><li>FLASH I PHP</li><li>JEZYKI PROGRAMOWANIA II</li><li>METODY NUMERYCZNE II</li><li>TEORIA GRAFOW</li></ul>\n<h4>Sposób 3 - arkusz kalkulacyjny</h4>\n<ol><li><strong>Tabela przestawna</strong>: zaimportuj wypozyczenia.txt. Pole PESEL → wiersze. Pole TYTUL → wartości (Licznik).</li><li>Sortuj malejąco wg licznika. Pierwszy wiersz to PESEL z największą liczbą.</li><li><strong>VLOOKUP</strong> w studenci.txt po PESEL → imię, nazwisko.</li><li><strong>Filtruj</strong> wypozyczenia.txt wg tego PESEL → uzyskaj listę tytułów.</li></ol>\n<h4>Reference informatyczny - SQL agregacja</h4>\n<blockquote>Reference - Klauzule SQL do tego typu zadania:<br>- <code>GROUP BY</code> - grupuje rekordy wg pola; każda grupa to jedna linia wyniku.<br>- <code>COUNT(*)</code> - liczba rekordów w grupie.<br>- <code>ORDER BY DESC LIMIT 1</code> - wybiera grupę z największą liczbą.<br>- <strong>Podzapytanie skorelowane</strong> - pozwala odwołać się do wyniku w innej części.<br>- <code>JOIN ON</code> - łączy dwie tabele po kluczu.<br><br>Reference - Alternatywa zamiast LIMIT 1 + ORDER BY (MAX):<br>```sql<br>WHERE COUNT(<em>) = (SELECT MAX(c) FROM (SELECT COUNT(</em>) AS c FROM wypozyczenia GROUP BY pesel))<br>```<br>Jest bezpieczniej gdy chcemy WSZYSTKICH osób z maksimum, nie tylko jednej.</blockquote>\n<h4>Schemat oceniania CKE</h4>\n<blockquote>Klucz CKE (zadanie 5.1, max 2 pkt):<br>- <strong>2 pkt</strong> - imię, nazwisko ORAZ wszystkie tytuły<br>- <strong>1 pkt</strong> - tylko imię i nazwisko ALBO tylko tytuły<br>- <strong>0 pkt</strong> - odpowiedź niepełna lub błędna</blockquote>\n<h4>Typowe pułapki</h4>\n<ul><li><strong>Nieuwzględnienie wszystkich tytułów</strong> - może być pominięcie 1 z 4. Klucz wymaga <strong>wszystkich</strong>.</li><li><strong>PESEL jako liczba</strong> - PESEL to 11 cyfr; w int może wystąpić overflow w niektórych językach. Lepiej traktować jako string.</li><li><strong>Kodowanie pliku</strong> - pliki CKE zwykle w Windows-1250 (polskie znaki). W Pythonie: <code>encoding=&#x27;windows-1250&#x27;</code> lub <code>&#x27;cp1250&#x27;</code>.</li><li><strong>Separator</strong> - w plikach CKE często TAB; sprawdzić w pierwszej linii.</li><li><strong>Pomylenie wypożyczeń (lp, pesel, tytul) z meldunkiem (pesel, id_pok)</strong> - meldunek nie ma tytułów, służy tylko do zameldowania w pokojach.</li></ul>\n<h4>Złożoność obliczeniowa</h4>\n<ul><li>Wczytanie plików: O(S + W) gdzie S = liczba studentów, W = liczba wypożyczeń.</li><li>Counter agregujący: O(W).</li><li>Wyszukanie max: O(unikalnych PESEL).</li><li><strong>Łącznie: O(S + W).</strong></li></ul>"}]}