{"id":"informatyka-2018-maj-matura-rozszerzona/zad/5.1","paper_id":"informatyka-2018-maj-matura-rozszerzona","number":"5.1","points":2,"ptype":"open","subject":"informatyka","category":"matura","year":2018,"month":"maj","level":"rozszerzona","text":"Zadanie 5. Zbiornik\n\nRzeka Wirka co roku wylewała. Aby temu zapobiec, wybudowano na rzece zbiornik retencyjny. W kolejnych wierszach pliku woda.txt znajdują się dane dotyczące dziennego dopływu wody z rzeki Wirki do zbiornika retencyjnego w kolejnych dniach z lat 2008-2017. Plik zawiera 3 653 wiersze. W każdym wierszu podane są dane: data (rrrr-mm-dd) oraz liczba metrów sześciennych wody, jaka dopływała do zbiornika w ciągu doby. Dane oddzielone są znakami tabulacji.\n\nPrzykład:\n2008-01-01 | 2275\n2008-01-02 | 2831\n2008-01-03 | 4615\n2008-01-04 | 4084\n2008-01-05 | 3258\n\nPodaj rok, w którym zbiornik retencyjny został zasilony łącznie największą liczbą metrów sześciennych wody z rzeki Wirki.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Rok 2015**\n\n## Sposób 1 - agregacja po roku\n\n**Idea:** dla każdej daty wyciągamy rok (pierwsze 4 znaki), sumujemy dopływy per rok, znajdujemy maksimum.\n\n## Sposób 2 - Python\n\n```python\nfrom collections import defaultdict\n\nsumy = defaultdict(int)\nwith open('woda.txt', encoding='utf-8') as f:\nfor linia in f:\ncz = linia.strip().split('\\t')\nif len(cz) != 2:\ncontinue\ndata, dop_str = cz\nrok = data[:4]\nsumy[rok] += int(dop_str)\n\nnajwiekszy = max(sumy.items(), key=lambda x: x[1])\nprint(f\"Rok: {najwiekszy[0]}, suma = {najwiekszy[1]}\") # 2015,\n\nfor rok, s in sorted(sumy.items()):\nprint(f\"{rok}: {s}\")\n\n## Sposób 3 - SQL\n\n```sql\nSELECT\nSUBSTRING(data, 1, 4) AS rok,\nSUM(doplyw) AS suma\nFROM woda\nGROUP BY SUBSTRING(data, 1, 4)\nORDER BY suma DESC\nLIMIT 1;\n\n## Sposób 4 - arkusz kalkulacyjny\n\n1. Otwórz woda.txt (separator: tabulacja).\n2. Kolumna A: data, B: dopływ.\n3. Kolumna C (pomocnicza): `=LEWY(A2; 4)` - rok jako string.\n4. **Tabela przestawna**: wiersze = C (rok), wartości = SUMA B.\n5. Sortuj malejąco - pierwszy wiersz to **2015** z najwyższą sumą.\n\nAlternatywnie z formuły:\n- F1:F10 - lata 2008 2017\n- G1: `=SUMA.JEŻELI(C:C; F1; B:B)` - suma dla danego roku.\n- Sortuj G malejąco lub `=INDEKS(F:F; PODAJ.POZYCJĘ(MAX(G:G); G:G; 0))` → 2015.\n\n## Sposób 5 - C++ / Pascal\n\n**C++:**\n```cpp\n#include <iostream>\n#include <fstream>\n#include <string>\n#include <map>\nusing namespace std;\n\nint main() {\nifstream f(\"woda.txt\");\nmap<string, long long> sumy;\nstring data, dopStr;\nwhile (f >> data >> dopStr) {\nstring rok = data.substr(0, 4);\nsumy[rok] += stoll(dopStr);\n}\nstring maxRok;\nlong long maxSuma = 0;\nfor (auto& [r, s] : sumy) {\nif (s > maxSuma) { maxSuma = s; maxRok = r; }\n}\ncout << \"Rok: \" << maxRok << \" suma: \" << maxSuma << endl;\nreturn 0;\n}\n\n## Reference informatyczny - agregacja danych\n\n> Reference - Wyciąganie roku z daty:\n> - **Format ISO 8601** (rrrr-mm-dd): rok to pierwsze 4 znaki → `data[:4]` (Python), `LEFT(data, 4)` (SQL), `Copy(data, 1, 4)` (Pascal).\n> - **W bazie danych** z typem DATE: `YEAR(data)` (MySQL) lub `EXTRACT(YEAR FROM data)` (PostgreSQL).\n>\n> Reference - defaultdict:\n> - **Python**: `defaultdict(int)` automatycznie inicjalizuje 0 dla nowych kluczy.\n> - **C++**: `std::map` z `operator[]` zachowuje się podobnie (auto-insert).\n> - **Alternatywa**: `dict.get(rok, 0) + 1` lub `Counter`.\n>\n> Reference - Agregacja sumująca:\n> - W SQL: `GROUP BY`. W Pythonie: słownik. W C++: map.\n> - **Complexity**: O(N) z dobrym hash/tree.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 5.1, max 2 pkt):\n> - **2 pkt** - odpowiedź **Rok 2015**\n> - **0 pkt** - błędna lub brak\n>\n> **Uwaga: NIE PRZYZNAJE SIĘ 1 PUNKTU.**\n\n## Typowe pułapki\n\n- **Sortowanie alfabetyczne lat zamiast wg sumy** - wynik byłby \"2008\" jako pierwszy.\n- **Pominięcie konwersji int** - w Python `int(dop_str)` konieczne, inaczej konkatenacja stringów.\n- **Pomyłka separatora** - TAB (\\t), nie spacja czy przecinek.\n- **Pomyłka roku - wziąć ostatnie 4 cyfry zamiast pierwszych** - `data[-4:]` da dzień + miesiąc; powinno być `data[:4]`.\n- **Brak EOL na końcu pliku** - większość parserów radzi sobie, ale uwaga w Pascal.\n\n## Złożoność obliczeniowa\n\n- Wczytanie 3653 wierszy: O(N).\n- Agregacja: O(N) z O(1) na wstawienie do mapy.\n- Znalezienie max: O(10) (10 lat).\n- **Łącznie: O(N) ≈ 3653 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 2018 (rozszerzona)","subject_label":"Informatyka","category_label":"Matura","text_html":"<p>Zadanie 5. Zbiornik</p>\n<p>Rzeka Wirka co roku wylewała. Aby temu zapobiec, wybudowano na rzece zbiornik retencyjny. W kolejnych wierszach pliku woda.txt znajdują się dane dotyczące dziennego dopływu wody z rzeki Wirki do zbiornika retencyjnego w kolejnych dniach z lat 2008-2017. Plik zawiera 3 653 wiersze. W każdym wierszu podane są dane: data (rrrr-mm-dd) oraz liczba metrów sześciennych wody, jaka dopływała do zbiornika w ciągu doby. Dane oddzielone są znakami tabulacji.</p>\n<p>Przykład:<br>2008-01-01 | 2275<br>2008-01-02 | 2831<br>2008-01-03 | 4615<br>2008-01-04 | 4084<br>2008-01-05 | 3258</p>\n<p>Podaj rok, w którym zbiornik retencyjny został zasilony łącznie największą liczbą metrów sześciennych wody z rzeki Wirki.</p>","solutions":[{"source":"maturazai","label":"maturazai.pl (AI)","kind":"text","html":"<h4>Poprawna odpowiedź</h4>\n<p><strong>Rok 2015</strong></p>\n<h4>Sposób 1 - agregacja po roku</h4>\n<p><strong>Idea:</strong> dla każdej daty wyciągamy rok (pierwsze 4 znaki), sumujemy dopływy per rok, znajdujemy maksimum.</p>\n<h4>Sposób 2 - Python</h4>\n<p>```python<br>from collections import defaultdict</p>\n<p>sumy = defaultdict(int)<br>with open(&#x27;woda.txt&#x27;, encoding=&#x27;utf-8&#x27;) as f:<br>for linia in f:<br>cz = linia.strip().split(&#x27;\\t&#x27;)<br>if len(cz) != 2:<br>continue<br>data, dop_str = cz<br>rok = data[:4]<br>sumy[rok] += int(dop_str)</p>\n<p>najwiekszy = max(sumy.items(), key=lambda x: x[1])<br>print(f&quot;Rok: {najwiekszy[0]}, suma = {najwiekszy[1]}&quot;) # 2015,</p>\n<p>for rok, s in sorted(sumy.items()):<br>print(f&quot;{rok}: {s}&quot;)</p>\n<h4>Sposób 3 - SQL</h4>\n<p>```sql<br>SELECT<br>SUBSTRING(data, 1, 4) AS rok,<br>SUM(doplyw) AS suma<br>FROM woda<br>GROUP BY SUBSTRING(data, 1, 4)<br>ORDER BY suma DESC<br>LIMIT 1;</p>\n<h4>Sposób 4 - arkusz kalkulacyjny</h4>\n<ol><li>Otwórz woda.txt (separator: tabulacja).</li><li>Kolumna A: data, B: dopływ.</li><li>Kolumna C (pomocnicza): <code>=LEWY(A2; 4)</code> - rok jako string.</li><li><strong>Tabela przestawna</strong>: wiersze = C (rok), wartości = SUMA B.</li><li>Sortuj malejąco - pierwszy wiersz to <strong>2015</strong> z najwyższą sumą.</li></ol>\n<p>Alternatywnie z formuły:</p>\n<ul><li>F1:F10 - lata 2008 2017</li><li>G1: <code>=SUMA.JEŻELI(C:C; F1; B:B)</code> - suma dla danego roku.</li><li>Sortuj G malejąco lub <code>=INDEKS(F:F; PODAJ.POZYCJĘ(MAX(G:G); G:G; 0))</code> → 2015.</li></ul>\n<h4>Sposób 5 - C++ / Pascal</h4>\n<p><strong>C++:</strong><br>```cpp<br>#include &lt;iostream&gt;<br>#include &lt;fstream&gt;<br>#include &lt;string&gt;<br>#include &lt;map&gt;<br>using namespace std;</p>\n<p>int main() {<br>ifstream f(&quot;woda.txt&quot;);<br>map&lt;string, long long&gt; sumy;<br>string data, dopStr;<br>while (f &gt;&gt; data &gt;&gt; dopStr) {<br>string rok = data.substr(0, 4);<br>sumy[rok] += stoll(dopStr);<br>}<br>string maxRok;<br>long long maxSuma = 0;<br>for (auto&amp; [r, s] : sumy) {<br>if (s &gt; maxSuma) { maxSuma = s; maxRok = r; }<br>}<br>cout &lt;&lt; &quot;Rok: &quot; &lt;&lt; maxRok &lt;&lt; &quot; suma: &quot; &lt;&lt; maxSuma &lt;&lt; endl;<br>return 0;<br>}</p>\n<h4>Reference informatyczny - agregacja danych</h4>\n<blockquote>Reference - Wyciąganie roku z daty:<br>- <strong>Format ISO 8601</strong> (rrrr-mm-dd): rok to pierwsze 4 znaki → <code>data[:4]</code> (Python), <code>LEFT(data, 4)</code> (SQL), <code>Copy(data, 1, 4)</code> (Pascal).<br>- <strong>W bazie danych</strong> z typem DATE: <code>YEAR(data)</code> (MySQL) lub <code>EXTRACT(YEAR FROM data)</code> (PostgreSQL).<br><br>Reference - defaultdict:<br>- <strong>Python</strong>: <code>defaultdict(int)</code> automatycznie inicjalizuje 0 dla nowych kluczy.<br>- <strong>C++</strong>: <code>std::map</code> z <code>operator[]</code> zachowuje się podobnie (auto-insert).<br>- <strong>Alternatywa</strong>: <code>dict.get(rok, 0) + 1</code> lub <code>Counter</code>.<br><br>Reference - Agregacja sumująca:<br>- W SQL: <code>GROUP BY</code>. W Pythonie: słownik. W C++: map.<br>- <strong>Complexity</strong>: O(N) z dobrym hash/tree.</blockquote>\n<h4>Schemat oceniania CKE</h4>\n<blockquote>Klucz CKE (zadanie 5.1, max 2 pkt):<br>- <strong>2 pkt</strong> - odpowiedź <strong>Rok 2015</strong><br>- <strong>0 pkt</strong> - błędna lub brak<br><br><strong>Uwaga: NIE PRZYZNAJE SIĘ 1 PUNKTU.</strong></blockquote>\n<h4>Typowe pułapki</h4>\n<ul><li><strong>Sortowanie alfabetyczne lat zamiast wg sumy</strong> - wynik byłby &quot;2008&quot; jako pierwszy.</li><li><strong>Pominięcie konwersji int</strong> - w Python <code>int(dop_str)</code> konieczne, inaczej konkatenacja stringów.</li><li><strong>Pomyłka separatora</strong> - TAB (\\t), nie spacja czy przecinek.</li><li><strong>Pomyłka roku - wziąć ostatnie 4 cyfry zamiast pierwszych</strong> - <code>data[-4:]</code> da dzień + miesiąc; powinno być <code>data[:4]</code>.</li><li><strong>Brak EOL na końcu pliku</strong> - większość parserów radzi sobie, ale uwaga w Pascal.</li></ul>\n<h4>Złożoność obliczeniowa</h4>\n<ul><li>Wczytanie 3653 wierszy: O(N).</li><li>Agregacja: O(N) z O(1) na wstawienie do mapy.</li><li>Znalezienie max: O(10) (10 lat).</li><li><strong>Łącznie: O(N) ≈ 3653 operacji.</strong></li></ul>"}]}