{"id":"informatyka-2017-maj-matura-rozszerzona/zad/5.2","paper_id":"informatyka-2017-maj-matura-rozszerzona","number":"5.2","points":2,"ptype":"open","subject":"informatyka","category":"matura","year":2017,"month":"maj","level":"rozszerzona","text":"Kontekst - patrz zadanie 5.1.\n\nPodaj listę zawierającą nazwy drużyn, z którymi drużyna Galop Kucykowo ma zerowy bilans bramkowy, tzn. łączna liczba bramek zdobytych we wszystkich meczach rozegranych z daną drużyną jest równa łącznej liczbie bramek straconych w tych meczach.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Drużyny z zerowym bilansem bramkowym z Galop Kucykowo:**\n- **Zwinne Mewy** (Id_druzyny = 84)\n- **Nocne Pumy** (Id_druzyny = 48)\n\n## Sposób 1 - SQL\n\n```sql\nSELECT d.Nazwa,\nSUM(w.Bramki_zdobyte) AS Z,\nSUM(w.Bramki_stracone) AS S\nFROM wyniki w\nJOIN druzyny d ON w.Id_druzyny = d.Id_druzyny\nGROUP BY d.Id_druzyny, d.Nazwa\nHAVING SUM(w.Bramki_zdobyte) = SUM(w.Bramki_stracone);\n\nWynik:\nZwinne Mewy | X | X\nNocne Pumy | Y | Y\n\n## Sposób 2 - Python\n\n```python\nfrom collections import defaultdict\n\n# Wczytaj drużyny\ndruzyny = {} # Id → Nazwa\nwith open('druzyny.txt', encoding='utf-8') as f:\nnext(f)\nfor line in f:\nidd, nazwa, miasto = line.strip().split('\\t')\ndruzyny[int(idd)] = nazwa\n\n# Agreguj zdobyte/stracone per Id\nzdobyte = defaultdict(int)\nstracone = defaultdict(int)\nwith open('wyniki.txt', encoding='utf-8') as f:\nnext(f)\nfor line in f:\nparts = line.strip().split('\\t')\nidd = int(parts[3])\nzdobyte[idd] += int(parts[5])\nstracone[idd] += int(parts[6])\n\nfor idd in zdobyte:\nif zdobyte[idd] == stracone[idd]:\nprint(druzyny[idd])\n# Output:\n# Zwinne Mewy\n# Nocne Pumy\n\n## Sposób 3 - arkusz kalkulacyjny\n\n1. Zaimportuj wyniki.txt do kolumn A-G.\n2. Tabela przestawna: Wiersze = Id_druzyny, Wartości = SUMA Bramki_zdobyte, SUMA Bramki_stracone.\n3. Dodaj kolumnę różnicy: Zdobyte - Stracone.\n4. Filtruj wiersze z różnicą = 0.\n5. WYSZUKAJ.PIONOWO po Id_druzyny → Nazwa.\n\n## Reference algorytmiczny - agregacja z warunkiem na wynikach\n\n> Reference - HAVING z agregatami:\n> - `HAVING SUM(a) = SUM(b)` filtruje grupy po WARTOŚCIACH agregatów.\n> - Różnica vs WHERE: WHERE działa na pojedynczych wierszach, HAVING na grupach.\n> - Klauzula HAVING wymaga GROUP BY (lub SELECT z agregatem bez kolumn).\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 5.2, max 2 pkt):\n> - **2 pkt** - za podanie dwóch poprawnych nazw drużyn (Zwinne Mewy, Nocne Pumy)\n> - **1 pkt** - za podanie poprawnych dwóch Id_druzyny (84 i 48), ale bez nazw\n> - **0 pkt** - błędna odpowiedź lub brak\n\n## Typowe pułapki\n\n- **Pominięcie nazwy** - treść wymaga NAZW drużyn, nie Id. Potrzebny JOIN z `druzyny`.\n- **Niewłaściwe agregowanie** - trzeba SUMOWAĆ po WSZYSTKICH meczach z daną drużyną, nie tylko pojedynczy mecz (jednomeczowy bilans).\n- **GROUP BY tylko po Id, nie po Nazwa** - w wielu SQL silnikach trzeba w GROUP BY mieć też kolumny SELECT, ale praktycznie Nazwa jest funkcyjnie zależna od Id, więc OK po GROUP BY Id.\n- **„Zerowy bilans\" interpretacja** - to NIE znaczy „zerowe bramki\", ale RÓŻNICA = 0 (zdobyte = stracone).\n\n## Złożoność obliczeniowa\n\n- SQL z GROUP BY: O(n log n) z indeksami.\n- Python: O(n) z słownikiem agregató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 2017 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura","text_html":"<p>Kontekst - patrz zadanie 5.1.</p>\n<p>Podaj listę zawierającą nazwy drużyn, z którymi drużyna Galop Kucykowo ma zerowy bilans bramkowy, tzn. łączna liczba bramek zdobytych we wszystkich meczach rozegranych z daną drużyną jest równa łącznej liczbie bramek straconych w tych meczach.</p>","solutions":[{"source":"maturazai","label":"maturazai.pl (AI)","kind":"text","html":"<h4>Poprawna odpowiedź</h4>\n<p><strong>Drużyny z zerowym bilansem bramkowym z Galop Kucykowo:</strong></p>\n<ul><li><strong>Zwinne Mewy</strong> (Id_druzyny = 84)</li><li><strong>Nocne Pumy</strong> (Id_druzyny = 48)</li></ul>\n<h4>Sposób 1 - SQL</h4>\n<p>```sql<br>SELECT d.Nazwa,<br>SUM(w.Bramki_zdobyte) AS Z,<br>SUM(w.Bramki_stracone) AS S<br>FROM wyniki w<br>JOIN druzyny d ON w.Id_druzyny = d.Id_druzyny<br>GROUP BY d.Id_druzyny, d.Nazwa<br>HAVING SUM(w.Bramki_zdobyte) = SUM(w.Bramki_stracone);</p>\n<p>Wynik:<br>Zwinne Mewy | X | X<br>Nocne Pumy | Y | Y</p>\n<h4>Sposób 2 - Python</h4>\n<p>```python<br>from collections import defaultdict</p>\n<h3>Wczytaj drużyny</h3>\n<p>druzyny = {} # Id → Nazwa<br>with open(&#x27;druzyny.txt&#x27;, encoding=&#x27;utf-8&#x27;) as f:<br>next(f)<br>for line in f:<br>idd, nazwa, miasto = line.strip().split(&#x27;\\t&#x27;)<br>druzyny[int(idd)] = nazwa</p>\n<h3>Agreguj zdobyte/stracone per Id</h3>\n<p>zdobyte = defaultdict(int)<br>stracone = defaultdict(int)<br>with open(&#x27;wyniki.txt&#x27;, encoding=&#x27;utf-8&#x27;) as f:<br>next(f)<br>for line in f:<br>parts = line.strip().split(&#x27;\\t&#x27;)<br>idd = int(parts[3])<br>zdobyte[idd] += int(parts[5])<br>stracone[idd] += int(parts[6])</p>\n<p>for idd in zdobyte:<br>if zdobyte[idd] == stracone[idd]:<br>print(druzyny[idd])</p>\n<h3>Output:</h3>\n<h3>Zwinne Mewy</h3>\n<h3>Nocne Pumy</h3>\n<h4>Sposób 3 - arkusz kalkulacyjny</h4>\n<ol><li>Zaimportuj wyniki.txt do kolumn A-G.</li><li>Tabela przestawna: Wiersze = Id_druzyny, Wartości = SUMA Bramki_zdobyte, SUMA Bramki_stracone.</li><li>Dodaj kolumnę różnicy: Zdobyte - Stracone.</li><li>Filtruj wiersze z różnicą = 0.</li><li>WYSZUKAJ.PIONOWO po Id_druzyny → Nazwa.</li></ol>\n<h4>Reference algorytmiczny - agregacja z warunkiem na wynikach</h4>\n<blockquote>Reference - HAVING z agregatami:<br>- <code>HAVING SUM(a) = SUM(b)</code> filtruje grupy po WARTOŚCIACH agregatów.<br>- Różnica vs WHERE: WHERE działa na pojedynczych wierszach, HAVING na grupach.<br>- Klauzula HAVING wymaga GROUP BY (lub SELECT z agregatem bez kolumn).</blockquote>\n<h4>Schemat oceniania CKE</h4>\n<blockquote>Klucz CKE (zadanie 5.2, max 2 pkt):<br>- <strong>2 pkt</strong> - za podanie dwóch poprawnych nazw drużyn (Zwinne Mewy, Nocne Pumy)<br>- <strong>1 pkt</strong> - za podanie poprawnych dwóch Id_druzyny (84 i 48), ale bez nazw<br>- <strong>0 pkt</strong> - błędna odpowiedź lub brak</blockquote>\n<h4>Typowe pułapki</h4>\n<ul><li><strong>Pominięcie nazwy</strong> - treść wymaga NAZW drużyn, nie Id. Potrzebny JOIN z <code>druzyny</code>.</li><li><strong>Niewłaściwe agregowanie</strong> - trzeba SUMOWAĆ po WSZYSTKICH meczach z daną drużyną, nie tylko pojedynczy mecz (jednomeczowy bilans).</li><li><strong>GROUP BY tylko po Id, nie po Nazwa</strong> - w wielu SQL silnikach trzeba w GROUP BY mieć też kolumny SELECT, ale praktycznie Nazwa jest funkcyjnie zależna od Id, więc OK po GROUP BY Id.</li><li><strong>„Zerowy bilans&quot; interpretacja</strong> - to NIE znaczy „zerowe bramki&quot;, ale RÓŻNICA = 0 (zdobyte = stracone).</li></ul>\n<h4>Złożoność obliczeniowa</h4>\n<ul><li>SQL z GROUP BY: O(n log n) z indeksami.</li><li>Python: O(n) z słownikiem agregatów.</li></ul>"}]}