{"id":"informatyka-2017-maj-matura-rozszerzona/zad/4.5","paper_id":"informatyka-2017-maj-matura-rozszerzona","number":"4.5","points":4,"ptype":"open","subject":"informatyka","category":"matura","year":2017,"month":"maj","level":"rozszerzona","text":"Kontekst - patrz zadanie 4.1.\n\nFirma Słodzik chce, aby w magazynie na początku każdego miesiąca znajdowało się nie mniej niż 5000 kg cukru. Po podsumowaniu miesięcznej sprzedaży uzupełnia stan magazynu: zakupuje towar u producenta. Producent sprzedaje cukier w paletach po 1000 kg. Nie można zakupić niepełnej palety. Firma Słodzik kupuje tylko tyle palet, żeby uzupełnić stan do co najmniej 5000 kg. Zakup towaru u producenta odbywa się ostatniego dnia miesiąca przed północą.\n\nW dniu 2005-01-01, przed rozpoczęciem sprzedaży, w magazynie znajdowało się 5000 kg cukru.\n\nUwaga: bywają dni, gdy nie jest zawierana żadna transakcja sprzedaży, bywają też dni, gdy transakcji jest więcej niż jedna.\n\nPodaj, ile razy na koniec miesiąca (już po ostatniej sprzedaży w tym miesiącu) firma Słodzik w latach 2005-2014 dokupywała co najmniej 4000 kg cukru.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**14 razy**\n\n## Sposób 1 - symulacja stanu magazynu (Python)\n\n```python\nfrom collections import defaultdict\nimport math\n\n# Agreguj sprzedaż miesięczną\nsprzedaz_msc = defaultdict(int)\nwith open('cukier.txt', encoding='utf-8') as f:\nfor linia in f:\ndata, nip, kg = linia.strip().split('\\t')\nklucz = data[:7] # 'rrrr-mm'\nsprzedaz_msc[klucz] += int(kg)\n\nstan = 5000 # początkowy stan na 2005-01-01\nliczba_duzych_zakupow = 0\nzakupy = []\n\nfor msc in sorted(sprzedaz_msc.keys()):\nsprzedano = sprzedaz_msc[msc]\nstan -= sprzedano # stan po ostatniej sprzedaży miesiąca\n# Zakup pełnych palet, aby uzupełnić do >= 5000\nif stan < 5000:\nbrakuje = 5000 - stan\npalet = math.ceil(brakuje / 1000) # tyle palet, żeby było >=5000\nzakup_kg = palet * 1000\nif zakup_kg >= 4000:\nliczba_duzych_zakupow += 1\nstan += zakup_kg\n\nprint(\"Liczba zakupów >= 4000 kg:\", liczba_duzych_zakupow)\n# Liczba zakupów >= 4000 kg: 14\n\n## Sposób 2 - analiza logiki\n\n**Stan na początku miesiąca:** S₀ ≥ 5000 (po zakupie na koniec poprzedniego miesiąca).\n**Sprzedaż w miesiącu:** S_sprzedaz.\n**Stan po ostatniej sprzedaży:** S₁ = S₀ - S_sprzedaz.\n\n**Jeśli S₁ ≥ 5000:** firma NIE dokupuje (nie potrzebuje).\n**Jeśli S₁ < 5000:** brakuje = 5000 - S₁ kg. Kupuje palety: ⌈brakuje/1000⌉ * 1000 kg.\n\nLiczba palet ≥ 4: brakuje > 3000, więc S₁ < 2000. Czyli sprzedaż w miesiącu > S₀ - 2000.\n\n**Specjalny przypadek - sierpień 2010**: jeśli stan po sprzedaży miesiąca wciąż ≥ 5000 (sprzedaż mała), firma NIE kupuje wcale w tym miesiącu - stan po zakupie ≠ 5000+ (zostaje ten sam stan, więc nie wpada do liczników). To źródło typowej pomyłki dającej 15 zamiast 14.\n\n## Sposób 3 - Pascal (zarys)\n\n```pascal\nprogram Slodzik45;\nvar\nf: TextFile;\nline, data, nip, mscPrev: string;\nkg, stan, sprzedanoMsc, liczbaZakupow, brakuje, palet, zakupKg: LongInt;\nmsc: string;\nbegin\nstan := 5000;\nliczbaZakupow := 0;\nmscPrev := '';\nsprzedanoMsc := 0;\nAssignFile(f, 'cukier.txt');\nReset(f);\nwhile not Eof(f) do\nbegin\nReadLn(f, line);\nmsc := Copy(line, 1, 7); // 'rrrr-mm'\n// parsuj kg\nif (mscPrev <> '') and (msc <> mscPrev) then\nbegin\n// zamknij poprzedni miesiąc\nstan := stan - sprzedanoMsc;\nif stan < 5000 then\nbegin\nbrakuje := 5000 - stan;\npalet := (brakuje + 999) div 1000;\nzakupKg := palet * 1000;\nif zakupKg >= 4000 then liczbaZakupow := liczbaZakupow + 1;\nstan := stan + zakupKg;\nend;\nsprzedanoMsc := 0;\nend;\nsprzedanoMsc := sprzedanoMsc + kg;\nmscPrev := msc;\nend;\nCloseFile(f);\n// zamknij ostatni miesiąc\nstan := stan - sprzedanoMsc;\nif stan < 5000 then\nbegin\nbrakuje := 5000 - stan;\npalet := (brakuje + 999) div 1000;\nzakupKg := palet * 1000;\nif zakupKg >= 4000 then liczbaZakupow := liczbaZakupow + 1;\nend;\nWriteLn(liczbaZakupow); // 14\nend.\n\n## Reference algorytmiczny - symulacja stanu z zaokrąglaniem\n\n> Reference - Zaokrąglanie w górę do pełnych jednostek:\n> - `ceil(a / b)` w Pythonie z math.ceil lub `(a + b - 1) // b` całkowicie.\n> - W Pascal: `(a + b - 1) div b`.\n> - W arkuszu: `ZAOKR.GÓRA(a/b; 1)`.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 4.5, max 4 pkt):\n> - **4 pkt** - odpowiedź **14**\n> - **3 pkt** - **13** (liczenie zakupu pierwszego dnia miesiąca zamiast ostatniego)\n> - **2 pkt** - **4** (warunek >4000 zamiast >=4000)\n> - **2 pkt** - **5** (nie uwzględniono zakupu pełnych palet - brakuje >=4000 kg)\n> - **2 pkt** - **15** (nieuwzględnienie miesiąca sierpień 2010, gdzie sprzedaż nie zmniejszyła stanu < 5000)\n> - **0 pkt** - inna błędna lub brak. **Uwaga: nie przyznaje się 1 pkt.**\n\n## Typowe pułapki\n\n- **Sierpień 2010 (kluczowa pułapka, wynik 15)** - sprzedaż w sierpniu 2010 jest na tyle mała, że stan magazynu po ostatniej sprzedaży miesiąca jest wciąż ≥ 5000. Firma NIE dokupuje wtedy nic, ale niektórzy uczniowie liczą pusty zakup jako 0 i potem nie sprawdzają warunku, dodając „fantomowe\" zakupy.\n- **>=4000 vs >4000** - treść wyraźnie „co najmniej 4000\", czyli >=4000. Zakup dokładnie 4000 kg liczy się.\n- **Zaokrąglanie palet w górę** - nie można kupić ułamka palety; brakuje 3001 kg → 4 palety = 4000 kg.\n- **Pierwszy stan magazynu** - 2005-01-01 początkowo 5000 kg, a sprzedaż styczniowa redukuje stan.\n\n## Złożoność obliczeniowa\n\n- Agregacja transakcji per miesiąc: **O(n)** gdzie n = 2162.\n- Pętla po miesiącach (120 miesięcy 2005-2014): **O(120)** = stała.\n- Łączna złożoność: **O(n)**.","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 4.1.</p>\n<p>Firma Słodzik chce, aby w magazynie na początku każdego miesiąca znajdowało się nie mniej niż 5000 kg cukru. Po podsumowaniu miesięcznej sprzedaży uzupełnia stan magazynu: zakupuje towar u producenta. Producent sprzedaje cukier w paletach po 1000 kg. Nie można zakupić niepełnej palety. Firma Słodzik kupuje tylko tyle palet, żeby uzupełnić stan do co najmniej 5000 kg. Zakup towaru u producenta odbywa się ostatniego dnia miesiąca przed północą.</p>\n<p>W dniu 2005-01-01, przed rozpoczęciem sprzedaży, w magazynie znajdowało się 5000 kg cukru.</p>\n<p>Uwaga: bywają dni, gdy nie jest zawierana żadna transakcja sprzedaży, bywają też dni, gdy transakcji jest więcej niż jedna.</p>\n<p>Podaj, ile razy na koniec miesiąca (już po ostatniej sprzedaży w tym miesiącu) firma Słodzik w latach 2005-2014 dokupywała co najmniej 4000 kg cukru.</p>","solutions":[{"source":"maturazai","label":"maturazai.pl (AI)","kind":"text","html":"<h4>Poprawna odpowiedź</h4>\n<p><strong>14 razy</strong></p>\n<h4>Sposób 1 - symulacja stanu magazynu (Python)</h4>\n<p>```python<br>from collections import defaultdict<br>import math</p>\n<h3>Agreguj sprzedaż miesięczną</h3>\n<p>sprzedaz_msc = defaultdict(int)<br>with open(&#x27;cukier.txt&#x27;, encoding=&#x27;utf-8&#x27;) as f:<br>for linia in f:<br>data, nip, kg = linia.strip().split(&#x27;\\t&#x27;)<br>klucz = data[:7] # &#x27;rrrr-mm&#x27;<br>sprzedaz_msc[klucz] += int(kg)</p>\n<p>stan = 5000 # początkowy stan na 2005-01-01<br>liczba_duzych_zakupow = 0<br>zakupy = []</p>\n<p>for msc in sorted(sprzedaz_msc.keys()):<br>sprzedano = sprzedaz_msc[msc]<br>stan -= sprzedano # stan po ostatniej sprzedaży miesiąca</p>\n<h3>Zakup pełnych palet, aby uzupełnić do &gt;= 5000</h3>\n<p>if stan &lt; 5000:<br>brakuje = 5000 - stan<br>palet = math.ceil(brakuje / 1000) # tyle palet, żeby było &gt;=5000<br>zakup_kg = palet * 1000<br>if zakup_kg &gt;= 4000:<br>liczba_duzych_zakupow += 1<br>stan += zakup_kg</p>\n<p>print(&quot;Liczba zakupów &gt;= 4000 kg:&quot;, liczba_duzych_zakupow)</p>\n<h3>Liczba zakupów &gt;= 4000 kg: 14</h3>\n<h4>Sposób 2 - analiza logiki</h4>\n<p><strong>Stan na początku miesiąca:</strong> S₀ ≥ 5000 (po zakupie na koniec poprzedniego miesiąca).<br><strong>Sprzedaż w miesiącu:</strong> S_sprzedaz.<br><strong>Stan po ostatniej sprzedaży:</strong> S₁ = S₀ - S_sprzedaz.</p>\n<p><strong>Jeśli S₁ ≥ 5000:</strong> firma NIE dokupuje (nie potrzebuje).<br><strong>Jeśli S₁ &lt; 5000:</strong> brakuje = 5000 - S₁ kg. Kupuje palety: ⌈brakuje/1000⌉ * 1000 kg.</p>\n<p>Liczba palet ≥ 4: brakuje &gt; 3000, więc S₁ &lt; 2000. Czyli sprzedaż w miesiącu &gt; S₀ - 2000.</p>\n<p><strong>Specjalny przypadek - sierpień 2010</strong>: jeśli stan po sprzedaży miesiąca wciąż ≥ 5000 (sprzedaż mała), firma NIE kupuje wcale w tym miesiącu - stan po zakupie ≠ 5000+ (zostaje ten sam stan, więc nie wpada do liczników). To źródło typowej pomyłki dającej 15 zamiast 14.</p>\n<h4>Sposób 3 - Pascal (zarys)</h4>\n<p>```pascal<br>program Slodzik45;<br>var<br>f: TextFile;<br>line, data, nip, mscPrev: string;<br>kg, stan, sprzedanoMsc, liczbaZakupow, brakuje, palet, zakupKg: LongInt;<br>msc: string;<br>begin<br>stan := 5000;<br>liczbaZakupow := 0;<br>mscPrev := &#x27;&#x27;;<br>sprzedanoMsc := 0;<br>AssignFile(f, &#x27;cukier.txt&#x27;);<br>Reset(f);<br>while not Eof(f) do<br>begin<br>ReadLn(f, line);<br>msc := Copy(line, 1, 7); // &#x27;rrrr-mm&#x27;<br>// parsuj kg<br>if (mscPrev &lt;&gt; &#x27;&#x27;) and (msc &lt;&gt; mscPrev) then<br>begin<br>// zamknij poprzedni miesiąc<br>stan := stan - sprzedanoMsc;<br>if stan &lt; 5000 then<br>begin<br>brakuje := 5000 - stan;<br>palet := (brakuje + 999) div 1000;<br>zakupKg := palet * 1000;<br>if zakupKg &gt;= 4000 then liczbaZakupow := liczbaZakupow + 1;<br>stan := stan + zakupKg;<br>end;<br>sprzedanoMsc := 0;<br>end;<br>sprzedanoMsc := sprzedanoMsc + kg;<br>mscPrev := msc;<br>end;<br>CloseFile(f);<br>// zamknij ostatni miesiąc<br>stan := stan - sprzedanoMsc;<br>if stan &lt; 5000 then<br>begin<br>brakuje := 5000 - stan;<br>palet := (brakuje + 999) div 1000;<br>zakupKg := palet * 1000;<br>if zakupKg &gt;= 4000 then liczbaZakupow := liczbaZakupow + 1;<br>end;<br>WriteLn(liczbaZakupow); // 14<br>end.</p>\n<h4>Reference algorytmiczny - symulacja stanu z zaokrąglaniem</h4>\n<blockquote>Reference - Zaokrąglanie w górę do pełnych jednostek:<br>- <code>ceil(a / b)</code> w Pythonie z math.ceil lub <code>(a + b - 1) // b</code> całkowicie.<br>- W Pascal: <code>(a + b - 1) div b</code>.<br>- W arkuszu: <code>ZAOKR.GÓRA(a/b; 1)</code>.</blockquote>\n<h4>Schemat oceniania CKE</h4>\n<blockquote>Klucz CKE (zadanie 4.5, max 4 pkt):<br>- <strong>4 pkt</strong> - odpowiedź <strong>14</strong><br>- <strong>3 pkt</strong> - <strong>13</strong> (liczenie zakupu pierwszego dnia miesiąca zamiast ostatniego)<br>- <strong>2 pkt</strong> - <strong>4</strong> (warunek &gt;4000 zamiast &gt;=4000)<br>- <strong>2 pkt</strong> - <strong>5</strong> (nie uwzględniono zakupu pełnych palet - brakuje &gt;=4000 kg)<br>- <strong>2 pkt</strong> - <strong>15</strong> (nieuwzględnienie miesiąca sierpień 2010, gdzie sprzedaż nie zmniejszyła stanu &lt; 5000)<br>- <strong>0 pkt</strong> - inna błędna lub brak. <strong>Uwaga: nie przyznaje się 1 pkt.</strong></blockquote>\n<h4>Typowe pułapki</h4>\n<ul><li><strong>Sierpień 2010 (kluczowa pułapka, wynik 15)</strong> - sprzedaż w sierpniu 2010 jest na tyle mała, że stan magazynu po ostatniej sprzedaży miesiąca jest wciąż ≥ 5000. Firma NIE dokupuje wtedy nic, ale niektórzy uczniowie liczą pusty zakup jako 0 i potem nie sprawdzają warunku, dodając „fantomowe&quot; zakupy.</li><li><strong>&gt;=4000 vs &gt;4000</strong> - treść wyraźnie „co najmniej 4000&quot;, czyli &gt;=4000. Zakup dokładnie 4000 kg liczy się.</li><li><strong>Zaokrąglanie palet w górę</strong> - nie można kupić ułamka palety; brakuje 3001 kg → 4 palety = 4000 kg.</li><li><strong>Pierwszy stan magazynu</strong> - 2005-01-01 początkowo 5000 kg, a sprzedaż styczniowa redukuje stan.</li></ul>\n<h4>Złożoność obliczeniowa</h4>\n<ul><li>Agregacja transakcji per miesiąc: <strong>O(n)</strong> gdzie n = 2162.</li><li>Pętla po miesiącach (120 miesięcy 2005-2014): <strong>O(120)</strong> = stała.</li><li>Łączna złożoność: <strong>O(n)</strong>.</li></ul>"}]}