{"id":"informatyka-2017-maj-matura-rozszerzona/zad/4.4","paper_id":"informatyka-2017-maj-matura-rozszerzona","number":"4.4","points":3,"ptype":"open","subject":"informatyka","category":"matura","year":2017,"month":"maj","level":"rozszerzona","text":"Kontekst - patrz zadanie 4.1.\n\nNa potrzeby zadania 4.4 załóżmy, że firma Słodzik wprowadziła system premiowania klientów hurtowych, który obejmuje lata 2005-2014. Klient otrzymuje przy zakupie rabat, którego wysokość zależy od łącznej ilości cukru zakupionego do tej pory przez tego klienta, **wliczając w to ilość cukru z bieżącej transakcji sprzedaży**. Wysokość rabatu za każdy kilogram cukru w bieżącej transakcji wynosi:\n- 5 gr, jeśli dotychczas zakupił co najmniej 100 kg, ale mniej niż 1000 kg;\n- 10 gr, jeśli dotychczas zakupił co najmniej 1000 kg, ale mniej niż 10000 kg;\n- 20 gr, jeśli dotychczas zakupił co najmniej 10000 kg.\n\nPodaj łączną wartość rabatów udzielonych przez firmę Słodzik.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Łączna wartość rabatów: 38 126,35 zł**\n\n## Sposób 1 - kluczowa interpretacja\n\n**Treść mówi:** rabat zależy od łącznej ilości cukru **wliczając bieżącą transakcję**. Czyli liczymy nowy stan łącznego zakupu klienta PO dodaniu kg z bieżącej transakcji, i według tego stanu (>= 100, >= 1000, >= 10000 kg) określamy rabat za każdy kg w bieżącej transakcji.\n\nProgi rabatów per kg w bieżącej transakcji:\n- nowa suma < 100 kg → 0 gr/kg (brak rabatu)\n- 100 ≤ nowa suma < 1000 → **5 gr/kg = 0,05 zł/kg**\n- 1000 ≤ nowa suma < 10 000 → **10 gr/kg = 0,10 zł/kg**\n- 10 000 ≤ nowa suma → **20 gr/kg = 0,20 zł/kg**\n\n## Sposób 2 - Python\n\n```python\nfrom collections import defaultdict\n\nsumy = defaultdict(int) # NIP → dotychczasowa łączna ilość\nlaczny_rabat = 0.0\n\nwith open('cukier.txt', encoding='utf-8') as f:\nfor linia in f:\ndata, nip, kg_s = linia.strip().split('\\t')\nkg = int(kg_s)\nsumy[nip] += kg # nowa suma WLICZAJĄC bieżącą transakcję\nnowa = sumy[nip]\nif nowa >= 10000:\nrabat_per_kg = 0.20\nelif nowa >= 1000:\nrabat_per_kg = 0.10\nelif nowa >= 100:\nrabat_per_kg = 0.05\nelse:\nrabat_per_kg = 0.0\nlaczny_rabat += kg * rabat_per_kg\n\nprint(f\"Łączny rabat: {laczny_rabat:.2f} zł\")\n# Łączny rabat: 38126.35 zł\n\n## Sposób 3 - arkusz kalkulacyjny\n\n1. Kolumny: A=Data, B=NIP, C=Kg.\n2. **Suma narastająca per klient** w kolumnie D:\n- D2: `=SUMA.JEŻELI($B$2:B2; B2; $C$2:C2)` - suma kg dla danego NIP od początku do bieżącego wiersza (włącznie).\n3. **Rabat per kg** w kolumnie E:\n- `=JEŻELI(D2>=10000; 0,20; JEŻELI(D2>=1000; 0,10; JEŻELI(D2>=100; 0,05; 0)))`\n4. **Rabat dla transakcji** w F: `=C2*E2`.\n5. **Suma F** = **38126,35**.\n\n## Sposób 4 - Pascal\n\n```pascal\nprogram Slodzik44;\nuses sysutils;\nvar\nf: TextFile;\nline, data, nip: string;\nkg, nowa, i, foundIdx: LongInt;\nrabatPerKg, laczny: Real;\nnipy: array[1 3000] of string;\nsumy: array[1 3000] of LongInt;\nn: Integer;\nbegin\nn := 0;\nlaczny := 0;\nAssignFile(f, 'cukier.txt');\nReset(f);\nwhile not Eof(f) do\nbegin\nReadLn(f, line);\n// [parsowanie split tabulacją: data, nip, kg]\n// Szukaj nip w tablicy nipy\nfoundIdx := 0;\nfor i := 1 to n do\nif nipy[i] = nip then foundIdx := i;\nif foundIdx = 0 then\nbegin\nn := n + 1;\nnipy[n] := nip;\nsumy[n] := 0;\nfoundIdx := n;\nend;\nsumy[foundIdx] := sumy[foundIdx] + kg;\nnowa := sumy[foundIdx];\nif nowa >= 10000 then rabatPerKg := 0.20\nelse if nowa >= 1000 then rabatPerKg := 0.10\nelse if nowa >= 100 then rabatPerKg := 0.05\nelse rabatPerKg := 0.0;\nlaczny := laczny + kg * rabatPerKg;\nend;\nCloseFile(f);\nWriteLn('Łączny rabat: ', laczny:0:2); // 38126.35\nend.\n\n## Reference algorytmiczny - narastający stan klienta\n\n> Reference - running sum per klient:\n> - Słownik nip → bieżąca suma kg.\n> - Każda transakcja UPDATE: suma[nip] += kg.\n> - Decyzja o rabacie na podstawie BIEŻĄCEJ sumy (po dodaniu kg).\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 4.4, max 3 pkt):\n> - **3 pkt** - poprawna odpowiedź **38 126,35 zł**\n> - **2 pkt** - **38 116,80 zł** (rabaty dla wartości **większych niż** 100/1000/10000, zamiast >=)\n> - **2 pkt** - **37 175,75 zł** (rabat NIE uwzględnia kg z bieżącej transakcji)\n> - **1 pkt** - **176,30 zł** (rabat nie pomnożony przez liczbę kg)\n> - **0 pkt** - inna błędna lub brak\n\n## Typowe pułapki\n\n- **„Większe od 100\" vs „co najmniej 100\"** - treść wyraźnie mówi „co najmniej\" (>=), nie „więcej niż\" (>). Granica 100 powinna już aktywować rabat 5 gr.\n- **Pominięcie bieżącej transakcji w sumie** - uczeń liczy rabat na podstawie sumy SPRZED dodania bieżącej transakcji. Treść mówi „wliczając\", więc dodaj kg najpierw.\n- **Pominięcie pomnożenia rabatu przez kg** - łatwo zapomnieć, że rabat to **per kg w bieżącej transakcji**, nie ryczałt.\n- **Kolejność progów w if** - trzeba sprawdzać od największego (>=10000) do najmniejszego, inaczej zła klasyfikacja.\n\n## Złożoność obliczeniowa\n\n- Pojedyncze przejście transakcji + lookup w słowniku: **O(n)** gdzie n = 2162.\n- Pamięć: O(k) gdzie k = liczba unikalnych NIPó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 4.1.</p>\n<p>Na potrzeby zadania 4.4 załóżmy, że firma Słodzik wprowadziła system premiowania klientów hurtowych, który obejmuje lata 2005-2014. Klient otrzymuje przy zakupie rabat, którego wysokość zależy od łącznej ilości cukru zakupionego do tej pory przez tego klienta, <strong>wliczając w to ilość cukru z bieżącej transakcji sprzedaży</strong>. Wysokość rabatu za każdy kilogram cukru w bieżącej transakcji wynosi:</p>\n<ul><li>5 gr, jeśli dotychczas zakupił co najmniej 100 kg, ale mniej niż 1000 kg;</li><li>10 gr, jeśli dotychczas zakupił co najmniej 1000 kg, ale mniej niż 10000 kg;</li><li>20 gr, jeśli dotychczas zakupił co najmniej 10000 kg.</li></ul>\n<p>Podaj łączną wartość rabatów udzielonych przez firmę Słodzik.</p>","solutions":[{"source":"maturazai","label":"maturazai.pl (AI)","kind":"text","html":"<h4>Poprawna odpowiedź</h4>\n<p><strong>Łączna wartość rabatów: 38 126,35 zł</strong></p>\n<h4>Sposób 1 - kluczowa interpretacja</h4>\n<p><strong>Treść mówi:</strong> rabat zależy od łącznej ilości cukru <strong>wliczając bieżącą transakcję</strong>. Czyli liczymy nowy stan łącznego zakupu klienta PO dodaniu kg z bieżącej transakcji, i według tego stanu (&gt;= 100, &gt;= 1000, &gt;= 10000 kg) określamy rabat za każdy kg w bieżącej transakcji.</p>\n<p>Progi rabatów per kg w bieżącej transakcji:</p>\n<ul><li>nowa suma &lt; 100 kg → 0 gr/kg (brak rabatu)</li><li>100 ≤ nowa suma &lt; 1000 → <strong>5 gr/kg = 0,05 zł/kg</strong></li><li>1000 ≤ nowa suma &lt; 10 000 → <strong>10 gr/kg = 0,10 zł/kg</strong></li><li>10 000 ≤ nowa suma → <strong>20 gr/kg = 0,20 zł/kg</strong></li></ul>\n<h4>Sposób 2 - Python</h4>\n<p>```python<br>from collections import defaultdict</p>\n<p>sumy = defaultdict(int) # NIP → dotychczasowa łączna ilość<br>laczny_rabat = 0.0</p>\n<p>with open(&#x27;cukier.txt&#x27;, encoding=&#x27;utf-8&#x27;) as f:<br>for linia in f:<br>data, nip, kg_s = linia.strip().split(&#x27;\\t&#x27;)<br>kg = int(kg_s)<br>sumy[nip] += kg # nowa suma WLICZAJĄC bieżącą transakcję<br>nowa = sumy[nip]<br>if nowa &gt;= 10000:<br>rabat_per_kg = 0.20<br>elif nowa &gt;= 1000:<br>rabat_per_kg = 0.10<br>elif nowa &gt;= 100:<br>rabat_per_kg = 0.05<br>else:<br>rabat_per_kg = 0.0<br>laczny_rabat += kg * rabat_per_kg</p>\n<p>print(f&quot;Łączny rabat: {laczny_rabat:.2f} zł&quot;)</p>\n<h3>Łączny rabat: 38126.35 zł</h3>\n<h4>Sposób 3 - arkusz kalkulacyjny</h4>\n<ol><li>Kolumny: A=Data, B=NIP, C=Kg.</li><li><strong>Suma narastająca per klient</strong> w kolumnie D:</li></ol>\n<ul><li>D2: <code>=SUMA.JEŻELI(<math xmlns=\"http://www.w3.org/1998/Math/MathML\" display=\"inline\"><mrow><mi>B</mi></mrow></math>2:B2; B2; <math xmlns=\"http://www.w3.org/1998/Math/MathML\" display=\"inline\"><mrow><mi>C</mi></mrow></math>2:C2)</code> - suma kg dla danego NIP od początku do bieżącego wiersza (włącznie).</li></ul>\n<ol><li><strong>Rabat per kg</strong> w kolumnie E:</li></ol>\n<ul><li><code>=JEŻELI(D2&gt;=10000; 0,20; JEŻELI(D2&gt;=1000; 0,10; JEŻELI(D2&gt;=100; 0,05; 0)))</code></li></ul>\n<ol><li><strong>Rabat dla transakcji</strong> w F: <code>=C2*E2</code>.</li><li><strong>Suma F</strong> = <strong>38126,35</strong>.</li></ol>\n<h4>Sposób 4 - Pascal</h4>\n<p>```pascal<br>program Slodzik44;<br>uses sysutils;<br>var<br>f: TextFile;<br>line, data, nip: string;<br>kg, nowa, i, foundIdx: LongInt;<br>rabatPerKg, laczny: Real;<br>nipy: array[1 3000] of string;<br>sumy: array[1 3000] of LongInt;<br>n: Integer;<br>begin<br>n := 0;<br>laczny := 0;<br>AssignFile(f, &#x27;cukier.txt&#x27;);<br>Reset(f);<br>while not Eof(f) do<br>begin<br>ReadLn(f, line);<br>// [parsowanie split tabulacją: data, nip, kg]<br>// Szukaj nip w tablicy nipy<br>foundIdx := 0;<br>for i := 1 to n do<br>if nipy[i] = nip then foundIdx := i;<br>if foundIdx = 0 then<br>begin<br>n := n + 1;<br>nipy[n] := nip;<br>sumy[n] := 0;<br>foundIdx := n;<br>end;<br>sumy[foundIdx] := sumy[foundIdx] + kg;<br>nowa := sumy[foundIdx];<br>if nowa &gt;= 10000 then rabatPerKg := 0.20<br>else if nowa &gt;= 1000 then rabatPerKg := 0.10<br>else if nowa &gt;= 100 then rabatPerKg := 0.05<br>else rabatPerKg := 0.0;<br>laczny := laczny + kg * rabatPerKg;<br>end;<br>CloseFile(f);<br>WriteLn(&#x27;Łączny rabat: &#x27;, laczny:0:2); // 38126.35<br>end.</p>\n<h4>Reference algorytmiczny - narastający stan klienta</h4>\n<blockquote>Reference - running sum per klient:<br>- Słownik nip → bieżąca suma kg.<br>- Każda transakcja UPDATE: suma[nip] += kg.<br>- Decyzja o rabacie na podstawie BIEŻĄCEJ sumy (po dodaniu kg).</blockquote>\n<h4>Schemat oceniania CKE</h4>\n<blockquote>Klucz CKE (zadanie 4.4, max 3 pkt):<br>- <strong>3 pkt</strong> - poprawna odpowiedź <strong>38 126,35 zł</strong><br>- <strong>2 pkt</strong> - <strong>38 116,80 zł</strong> (rabaty dla wartości <strong>większych niż</strong> 100/1000/10000, zamiast &gt;=)<br>- <strong>2 pkt</strong> - <strong>37 175,75 zł</strong> (rabat NIE uwzględnia kg z bieżącej transakcji)<br>- <strong>1 pkt</strong> - <strong>176,30 zł</strong> (rabat nie pomnożony przez liczbę kg)<br>- <strong>0 pkt</strong> - inna błędna lub brak</blockquote>\n<h4>Typowe pułapki</h4>\n<ul><li><strong>„Większe od 100&quot; vs „co najmniej 100&quot;</strong> - treść wyraźnie mówi „co najmniej&quot; (&gt;=), nie „więcej niż&quot; (&gt;). Granica 100 powinna już aktywować rabat 5 gr.</li><li><strong>Pominięcie bieżącej transakcji w sumie</strong> - uczeń liczy rabat na podstawie sumy SPRZED dodania bieżącej transakcji. Treść mówi „wliczając&quot;, więc dodaj kg najpierw.</li><li><strong>Pominięcie pomnożenia rabatu przez kg</strong> - łatwo zapomnieć, że rabat to <strong>per kg w bieżącej transakcji</strong>, nie ryczałt.</li><li><strong>Kolejność progów w if</strong> - trzeba sprawdzać od największego (&gt;=10000) do najmniejszego, inaczej zła klasyfikacja.</li></ul>\n<h4>Złożoność obliczeniowa</h4>\n<ul><li>Pojedyncze przejście transakcji + lookup w słowniku: <strong>O(n)</strong> gdzie n = 2162.</li><li>Pamięć: O(k) gdzie k = liczba unikalnych NIPów.</li></ul>"}]}