{"id":"informatyka-2018-maj-matura-rozszerzona/zad/5.2","paper_id":"informatyka-2018-maj-matura-rozszerzona","number":"5.2","points":2,"ptype":"open","subject":"informatyka","category":"matura","year":2018,"month":"maj","level":"rozszerzona","text":"Kontekst - patrz zadanie 5.1.\n\nJaki był najdłuższy okres liczony w dniach, w którym codziennie dopływało do zbiornika retencyjnego co najmniej 10 000 metrów sześciennych wody z rzeki Wirki? Jest tylko jeden taki okres. Podaj datę początkową i datę końcową tego okresu.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Okres: od 2015-03-17 do 2015-05-10**\n\n**Długość: 55 dni**\n\n## Sposób 1 - najdłuższa seria spełniająca warunek\n\n**Idea:** to klasyczny problem **najdłuższy ciąg w tablicy spełniający warunek**.\n\nIterujemy po dniach:\n- Jeśli `dopływ ≥ 10000` → zwiększ aktualny licznik serii, zapisz datę pierwszego dnia.\n- Jeśli `dopływ < 10000` → reset licznika.\n- Po każdym dniu sprawdź, czy aktualna seria jest najdłuższa; jeśli tak, zapisz daty.\n\n## Sposób 2 - Python\n\n```python\nlinie = []\nwith open('woda.txt', encoding='utf-8') as f:\nfor linia in f:\ncz = linia.strip().split('\\t')\nif len(cz) == 2:\ndata, dop = cz\nlinie.append((data, int(dop)))\n\nmax_dlugosc = 0\nmax_start = ''\nmax_koniec = ''\n\nakt_dlugosc = 0\nakt_start = ''\nakt_koniec = ''\n\nfor data, dop in linie:\nif dop >= 10000:\nif akt_dlugosc == 0:\nakt_start = data\nakt_dlugosc += 1\nakt_koniec = data\nif akt_dlugosc > max_dlugosc:\nmax_dlugosc = akt_dlugosc\nmax_start = akt_start\nmax_koniec = akt_koniec\nelse:\nakt_dlugosc = 0\n\nprint(f\"Od {max_start} do {max_koniec}, długość: {max_dlugosc} dni\")\n# Od 2015-03-17 do 2015-05-10, długość: 55 dni\n\n## Sposób 3 - arkusz kalkulacyjny\n\n1. Kolumny A (data), B (dopływ).\n2. Kolumna C: `=JEŻELI(B2>=10000; 1; 0)` - wskaźnik 1/0.\n3. Kolumna D (kumulatywna seria): D1=C1; D2=`=JEŻELI(C2=1; D1+1; 0)` - rośnie gdy spełnione, resetuje gdy nie.\n4. Znajdź max D: `=MAX(D:D)` → 55.\n5. Znajdź wiersz: `=PODAJ.POZYCJĘ(55; D:D; 0)` → numer wiersza końca serii (data końcowa = A[ten wiersz]).\n6. Data początkowa = data końcowa minus 54 dni (lub o pozycję A[wiersz_końca - 54]).\n\n## Sposób 4 - C++\n\n```cpp\n#include <iostream>\n#include <fstream>\n#include <string>\nusing namespace std;\n\nint main() {\nifstream f(\"woda.txt\");\nstring data, dopStr, prevData = \"\", aktStart = \"\";\nint dop, aktDl = 0, maxDl = 0;\nstring maxStart = \"\", maxKoniec = \"\";\nwhile (f >> data >> dopStr) {\ndop = stoi(dopStr);\nif (dop >= 10000) {\nif (aktDl == 0) aktStart = data;\naktDl++;\nif (aktDl > maxDl) {\nmaxDl = aktDl;\nmaxStart = aktStart;\nmaxKoniec = data;\n}\n} else {\naktDl = 0;\n}\n}\ncout << \"Od \" << maxStart << \" do \" << maxKoniec << \" (\" << maxDl << \" dni)\" << endl;\nreturn 0;\n}\n\n## Reference informatyczny - najdłuższy podciąg spełniający warunek\n\n> Reference - Klasyczne zadania na ciągach:\n> - **Najdłuższy podciąg jedynek** (np. \"010111110001\" → 5).\n> - **Najdłuższa seria niemalejąca** w tablicy.\n> - **Najdłuższa seria z warunkiem** P(x) - uogólnienie.\n>\n> Reference - Algorytm \"running streak\":\n> - Single-pass O(n).\n> - 2 zmienne: `akt` (aktualna długość), `max` (najdłuższa do tej pory).\n> - Reset `akt = 0` gdy warunek nie spełniony.\n> - Aktualizacja `max = max(max, akt)`.\n>\n> Reference - Daty:\n> - W stringach format ISO (rrrr-mm-dd) zachowuje porządek leksykograficzny == chronologiczny.\n> - Można porównywać daty jako stringi bez konwersji.\n> - Daty są ciągłe w pliku (codziennie od 2008-01-01 do 2017-12-31).\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 5.2, max 2 pkt):\n> - **2 pkt** - obie daty prawidłowe (2015-03-17 i 2015-05-10)\n> - **1 pkt** - tylko jedna data ALBO tylko liczba dni (55)\n> - **0 pkt** - błędna lub brak\n\n## Typowe pułapki\n\n- **\"Co najmniej 10000\"** = `>= 10000`, NIE `> 10000`. Pominięcie wartości równej 10000.\n- **Brak resetowania licznika** - wynik byłby kumulatywny i bezsensowny.\n- **Pomyłka daty początkowej** - łatwo zapomnieć zapisać `akt_start` w momencie startu serii.\n- **Liczenie dni - `koniec - start + 1`** w datach, nie `koniec - start`.\n- **Konwersja int** - `int(dop_str)` w Python, bo bez tego porównanie string < string.\n- **Iteracja w niesortowanym pliku** - plik jest już chronologicznie (data rosnąco), więc iterujemy w kolejności.\n\n## Złożoność obliczeniowa\n\n- Single-pass: **O(N)** = O(3653).\n- Pamięć: O(1) dodatkowa.","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>Kontekst - patrz zadanie 5.1.</p>\n<p>Jaki był najdłuższy okres liczony w dniach, w którym codziennie dopływało do zbiornika retencyjnego co najmniej 10 000 metrów sześciennych wody z rzeki Wirki? Jest tylko jeden taki okres. Podaj datę początkową i datę końcową tego okresu.</p>","solutions":[{"source":"maturazai","label":"maturazai.pl (AI)","kind":"text","html":"<h4>Poprawna odpowiedź</h4>\n<p><strong>Okres: od 2015-03-17 do 2015-05-10</strong></p>\n<p><strong>Długość: 55 dni</strong></p>\n<h4>Sposób 1 - najdłuższa seria spełniająca warunek</h4>\n<p><strong>Idea:</strong> to klasyczny problem <strong>najdłuższy ciąg w tablicy spełniający warunek</strong>.</p>\n<p>Iterujemy po dniach:</p>\n<ul><li>Jeśli <code>dopływ ≥ 10000</code> → zwiększ aktualny licznik serii, zapisz datę pierwszego dnia.</li><li>Jeśli <code>dopływ &lt; 10000</code> → reset licznika.</li><li>Po każdym dniu sprawdź, czy aktualna seria jest najdłuższa; jeśli tak, zapisz daty.</li></ul>\n<h4>Sposób 2 - Python</h4>\n<p>```python<br>linie = []<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>data, dop = cz<br>linie.append((data, int(dop)))</p>\n<p>max_dlugosc = 0<br>max_start = &#x27;&#x27;<br>max_koniec = &#x27;&#x27;</p>\n<p>akt_dlugosc = 0<br>akt_start = &#x27;&#x27;<br>akt_koniec = &#x27;&#x27;</p>\n<p>for data, dop in linie:<br>if dop &gt;= 10000:<br>if akt_dlugosc == 0:<br>akt_start = data<br>akt_dlugosc += 1<br>akt_koniec = data<br>if akt_dlugosc &gt; max_dlugosc:<br>max_dlugosc = akt_dlugosc<br>max_start = akt_start<br>max_koniec = akt_koniec<br>else:<br>akt_dlugosc = 0</p>\n<p>print(f&quot;Od {max_start} do {max_koniec}, długość: {max_dlugosc} dni&quot;)</p>\n<h3>Od 2015-03-17 do 2015-05-10, długość: 55 dni</h3>\n<h4>Sposób 3 - arkusz kalkulacyjny</h4>\n<ol><li>Kolumny A (data), B (dopływ).</li><li>Kolumna C: <code>=JEŻELI(B2&gt;=10000; 1; 0)</code> - wskaźnik 1/0.</li><li>Kolumna D (kumulatywna seria): D1=C1; D2=<code>=JEŻELI(C2=1; D1+1; 0)</code> - rośnie gdy spełnione, resetuje gdy nie.</li><li>Znajdź max D: <code>=MAX(D:D)</code> → 55.</li><li>Znajdź wiersz: <code>=PODAJ.POZYCJĘ(55; D:D; 0)</code> → numer wiersza końca serii (data końcowa = A[ten wiersz]).</li><li>Data początkowa = data końcowa minus 54 dni (lub o pozycję A[wiersz_końca - 54]).</li></ol>\n<h4>Sposób 4 - C++</h4>\n<p>```cpp<br>#include &lt;iostream&gt;<br>#include &lt;fstream&gt;<br>#include &lt;string&gt;<br>using namespace std;</p>\n<p>int main() {<br>ifstream f(&quot;woda.txt&quot;);<br>string data, dopStr, prevData = &quot;&quot;, aktStart = &quot;&quot;;<br>int dop, aktDl = 0, maxDl = 0;<br>string maxStart = &quot;&quot;, maxKoniec = &quot;&quot;;<br>while (f &gt;&gt; data &gt;&gt; dopStr) {<br>dop = stoi(dopStr);<br>if (dop &gt;= 10000) {<br>if (aktDl == 0) aktStart = data;<br>aktDl++;<br>if (aktDl &gt; maxDl) {<br>maxDl = aktDl;<br>maxStart = aktStart;<br>maxKoniec = data;<br>}<br>} else {<br>aktDl = 0;<br>}<br>}<br>cout &lt;&lt; &quot;Od &quot; &lt;&lt; maxStart &lt;&lt; &quot; do &quot; &lt;&lt; maxKoniec &lt;&lt; &quot; (&quot; &lt;&lt; maxDl &lt;&lt; &quot; dni)&quot; &lt;&lt; endl;<br>return 0;<br>}</p>\n<h4>Reference informatyczny - najdłuższy podciąg spełniający warunek</h4>\n<blockquote>Reference - Klasyczne zadania na ciągach:<br>- <strong>Najdłuższy podciąg jedynek</strong> (np. &quot;010111110001&quot; → 5).<br>- <strong>Najdłuższa seria niemalejąca</strong> w tablicy.<br>- <strong>Najdłuższa seria z warunkiem</strong> P(x) - uogólnienie.<br><br>Reference - Algorytm &quot;running streak&quot;:<br>- Single-pass O(n).<br>- 2 zmienne: <code>akt</code> (aktualna długość), <code>max</code> (najdłuższa do tej pory).<br>- Reset <code>akt = 0</code> gdy warunek nie spełniony.<br>- Aktualizacja <code>max = max(max, akt)</code>.<br><br>Reference - Daty:<br>- W stringach format ISO (rrrr-mm-dd) zachowuje porządek leksykograficzny == chronologiczny.<br>- Można porównywać daty jako stringi bez konwersji.<br>- Daty są ciągłe w pliku (codziennie od 2008-01-01 do 2017-12-31).</blockquote>\n<h4>Schemat oceniania CKE</h4>\n<blockquote>Klucz CKE (zadanie 5.2, max 2 pkt):<br>- <strong>2 pkt</strong> - obie daty prawidłowe (2015-03-17 i 2015-05-10)<br>- <strong>1 pkt</strong> - tylko jedna data ALBO tylko liczba dni (55)<br>- <strong>0 pkt</strong> - błędna lub brak</blockquote>\n<h4>Typowe pułapki</h4>\n<ul><li><strong>&quot;Co najmniej 10000&quot;</strong> = <code>&gt;= 10000</code>, NIE <code>&gt; 10000</code>. Pominięcie wartości równej 10000.</li><li><strong>Brak resetowania licznika</strong> - wynik byłby kumulatywny i bezsensowny.</li><li><strong>Pomyłka daty początkowej</strong> - łatwo zapomnieć zapisać <code>akt_start</code> w momencie startu serii.</li><li><strong>Liczenie dni - <code>koniec - start + 1</code></strong> w datach, nie <code>koniec - start</code>.</li><li><strong>Konwersja int</strong> - <code>int(dop_str)</code> w Python, bo bez tego porównanie string &lt; string.</li><li><strong>Iteracja w niesortowanym pliku</strong> - plik jest już chronologicznie (data rosnąco), więc iterujemy w kolejności.</li></ul>\n<h4>Złożoność obliczeniowa</h4>\n<ul><li>Single-pass: <strong>O(N)</strong> = O(3653).</li><li>Pamięć: O(1) dodatkowa.</li></ul>"}]}