{"id":"informatyka-2017-maj-matura-rozszerzona/zad/6.2","paper_id":"informatyka-2017-maj-matura-rozszerzona","number":"6.2","points":2,"ptype":"open","subject":"informatyka","category":"matura","year":2017,"month":"maj","level":"rozszerzona","text":"Kontekst - patrz zadanie 6.1.\n\nPodaj, ile wynosi najmniejsza liczba wierszy, które należy usunąć, żeby obraz miał pionową oś symetrii. Obraz ma pionową oś symetrii, jeśli w każdym wierszu i-ty piksel od lewej strony przyjmuje tę samą wartość, co i-ty piksel od prawej strony, dla dowolnego 1 ≤ i ≤ 320.\n\nDla danych z pliku przyklad.txt wynikiem jest 3.","answer":null,"answer_text":null,"solution":"## Poprawna odpowiedź\n\n**Najmniejsza liczba wierszy do usunięcia: 149** (z 200 wierszy w `dane.txt`).\n\nDla `przyklad.txt`: 3.\n\nInterpretacja: obraz będzie miał pionową oś symetrii, jeśli zostawimy tylko te wiersze, które SAMODZIELNIE są palindromami (czytane od lewej = od prawej). Wystarczy zliczyć wiersze NIE-palindromowe - te trzeba usunąć.\n\nPionowa oś symetrii działa NIEZALEŻNIE w każdym wierszu - wiersz jest \"symetryczny\", gdy A[k] = A[321-k] dla k = 1 160 (lub równoważnie [0 159] przy indeksowaniu od 0).\n\n## Sposób 1 - Python (najczystszy)\n\n```python\nusuwajacych = 0\nwith open('dane.txt') as f:\nfor linia in f:\nwiersz = linia.split() # 320 stringow\n# Sprawdz palindrom\nif wiersz != wiersz[::-1]:\nusuwajacych += 1\n\nprint(usuwajacych) # 149\n\nLub jedno-linijkowo:\n```python\nwith open('dane.txt') as f:\nprint(sum(1 for l in f if (w := l.split()) != w[::-1]))\n\n## Sposób 2 - C++\n\n```cpp\n#include <iostream>\n#include <fstream>\n#include <vector>\nusing namespace std;\n\nint main() {\nifstream plik(\"dane.txt\");\nint do_usuniecia = 0;\nstring linia;\nwhile (getline(plik, linia)) {\nvector<int> w;\nsize_t pos = 0, next;\n// Parsuj liczby z linii\nwhile ((next = linia.find(' ', pos)) != string::npos) {\nw.push_back(stoi(linia.substr(pos, next - pos)));\npos = next + 1;\n}\nif (pos < linia.size()) w.push_back(stoi(linia.substr(pos)));\n// Sprawdz palindrom\nbool palindrom = true;\nint n = w.size();\nfor (int i = 0; i < n / 2; i++) {\nif (w[i] != w[n - 1 - i]) { palindrom = false; break; }\n}\nif (!palindrom) do_usuniecia++;\n}\ncout << do_usuniecia << endl; // 149\nreturn 0;\n}\n\n## Sposób 3 - Pascal\n\n```pascal\nprogram OsSymetrii;\nvar\nf: TextFile;\nwiersz: array[1 320] of Integer;\ni, j, n: Integer;\ndo_usuniecia: Integer;\npalindrom: Boolean;\nbegin\nAssignFile(f, 'dane.txt');\nReset(f);\ndo_usuniecia := 0;\nfor i := 1 to 200 do\nbegin\nfor j := 1 to 320 do Read(f, wiersz[j]);\nReadln(f);\npalindrom := True;\nfor j := 1 to 160 do\nif wiersz[j] <> wiersz[321 - j] then\nbegin\npalindrom := False;\nBreak;\nend;\nif not palindrom then Inc(do_usuniecia);\nend;\nCloseFile(f);\nWriteln(do_usuniecia); // 149\nend.\n\n## Reference algorytmiczny - sprawdzanie palindromu\n\n> Reference - palindromiczność wiersza:\n> - Wiersz jest palindromem ⇔ wiersz[i] = wiersz[n-1-i] dla każdego i ∈ [0, n/2).\n> - Złożoność: O(n/2) = O(n) na wiersz.\n> - W Pythonie najprościej: `wiersz == wiersz[::-1]` (operator slice odwracający listę).\n> - Dla 200 wierszy × 320 pikseli: łącznie 200 × 160 = 32 000 porównań. Szybko.\n\n## Schemat oceniania CKE\n\n> Klucz CKE (zadanie 6.2, max 2 pkt):\n> - **2 pkt** - prawidłowa odpowiedź: **149**.\n> - **0 pkt** - odpowiedź błędna lub brak.\n> - **UWAGA:** Nie przyznaje się 1 pkt.\n\n## Typowe pułapki\n\n- **Mylenie sensu pionowej osi symetrii** - to symetria LEWO-PRAWO (kolumna i = kolumna 321-i), a nie góra-dół.\n- **\"Najmniejsza liczba wierszy do usunięcia\"** - to po prostu liczba wierszy NIE-palindromowych (każdy taki MUSI być usunięty, palindromowe MOGĄ zostać).\n- **Indeksowanie 1 320 vs 0 319** - w Python od 0, w pseudokodzie CKE od 1. `wiersz[i] vs wiersz[321-i]` jeśli indeksujemy od 1, a `wiersz[i] vs wiersz[319-i]` od 0.\n- **Tylko połowa porównań wystarczy** - sprawdzaj `i` od 0 do n/2-1 (lub do n//2). Sprawdzanie wszystkich par jest podwójną pracą.\n- **Pomylenie z liczbą wierszy POZOSTAŁYCH** - pytanie o USUNIĘTE (149), nie zachowane (51 = 200 - 149).\n\n## Złożoność obliczeniowa\n\n- Wczytanie: O(n × m) = O(64 000).\n- Sprawdzenie palindromu per wiersz: O(m/2) = O(160) = O(m).\n- **Całkowita: O(n × m) = O(64 000)**, liniowa względem rozmiaru obrazu.","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 6.1.</p>\n<p>Podaj, ile wynosi najmniejsza liczba wierszy, które należy usunąć, żeby obraz miał pionową oś symetrii. Obraz ma pionową oś symetrii, jeśli w każdym wierszu i-ty piksel od lewej strony przyjmuje tę samą wartość, co i-ty piksel od prawej strony, dla dowolnego 1 ≤ i ≤ 320.</p>\n<p>Dla danych z pliku przyklad.txt wynikiem jest 3.</p>","solutions":[{"source":"maturazai","label":"maturazai.pl (AI)","kind":"text","html":"<h4>Poprawna odpowiedź</h4>\n<p><strong>Najmniejsza liczba wierszy do usunięcia: 149</strong> (z 200 wierszy w <code>dane.txt</code>).</p>\n<p>Dla <code>przyklad.txt</code>: 3.</p>\n<p>Interpretacja: obraz będzie miał pionową oś symetrii, jeśli zostawimy tylko te wiersze, które SAMODZIELNIE są palindromami (czytane od lewej = od prawej). Wystarczy zliczyć wiersze NIE-palindromowe - te trzeba usunąć.</p>\n<p>Pionowa oś symetrii działa NIEZALEŻNIE w każdym wierszu - wiersz jest &quot;symetryczny&quot;, gdy A[k] = A[321-k] dla k = 1 160 (lub równoważnie [0 159] przy indeksowaniu od 0).</p>\n<h4>Sposób 1 - Python (najczystszy)</h4>\n<p>```python<br>usuwajacych = 0<br>with open(&#x27;dane.txt&#x27;) as f:<br>for linia in f:<br>wiersz = linia.split() # 320 stringow</p>\n<h3>Sprawdz palindrom</h3>\n<p>if wiersz != wiersz[::-1]:<br>usuwajacych += 1</p>\n<p>print(usuwajacych) # 149</p>\n<p>Lub jedno-linijkowo:<br>```python<br>with open(&#x27;dane.txt&#x27;) as f:<br>print(sum(1 for l in f if (w := l.split()) != w[::-1]))</p>\n<h4>Sposób 2 - C++</h4>\n<p>```cpp<br>#include &lt;iostream&gt;<br>#include &lt;fstream&gt;<br>#include &lt;vector&gt;<br>using namespace std;</p>\n<p>int main() {<br>ifstream plik(&quot;dane.txt&quot;);<br>int do_usuniecia = 0;<br>string linia;<br>while (getline(plik, linia)) {<br>vector&lt;int&gt; w;<br>size_t pos = 0, next;<br>// Parsuj liczby z linii<br>while ((next = linia.find(&#x27; &#x27;, pos)) != string::npos) {<br>w.push_back(stoi(linia.substr(pos, next - pos)));<br>pos = next + 1;<br>}<br>if (pos &lt; linia.size()) w.push_back(stoi(linia.substr(pos)));<br>// Sprawdz palindrom<br>bool palindrom = true;<br>int n = w.size();<br>for (int i = 0; i &lt; n / 2; i++) {<br>if (w[i] != w[n - 1 - i]) { palindrom = false; break; }<br>}<br>if (!palindrom) do_usuniecia++;<br>}<br>cout &lt;&lt; do_usuniecia &lt;&lt; endl; // 149<br>return 0;<br>}</p>\n<h4>Sposób 3 - Pascal</h4>\n<p>```pascal<br>program OsSymetrii;<br>var<br>f: TextFile;<br>wiersz: array[1 320] of Integer;<br>i, j, n: Integer;<br>do_usuniecia: Integer;<br>palindrom: Boolean;<br>begin<br>AssignFile(f, &#x27;dane.txt&#x27;);<br>Reset(f);<br>do_usuniecia := 0;<br>for i := 1 to 200 do<br>begin<br>for j := 1 to 320 do Read(f, wiersz[j]);<br>Readln(f);<br>palindrom := True;<br>for j := 1 to 160 do<br>if wiersz[j] &lt;&gt; wiersz[321 - j] then<br>begin<br>palindrom := False;<br>Break;<br>end;<br>if not palindrom then Inc(do_usuniecia);<br>end;<br>CloseFile(f);<br>Writeln(do_usuniecia); // 149<br>end.</p>\n<h4>Reference algorytmiczny - sprawdzanie palindromu</h4>\n<blockquote>Reference - palindromiczność wiersza:<br>- Wiersz jest palindromem ⇔ wiersz[i] = wiersz[n-1-i] dla każdego i ∈ [0, n/2).<br>- Złożoność: O(n/2) = O(n) na wiersz.<br>- W Pythonie najprościej: <code>wiersz == wiersz[::-1]</code> (operator slice odwracający listę).<br>- Dla 200 wierszy × 320 pikseli: łącznie 200 × 160 = 32 000 porównań. Szybko.</blockquote>\n<h4>Schemat oceniania CKE</h4>\n<blockquote>Klucz CKE (zadanie 6.2, max 2 pkt):<br>- <strong>2 pkt</strong> - prawidłowa odpowiedź: <strong>149</strong>.<br>- <strong>0 pkt</strong> - odpowiedź błędna lub brak.<br>- <strong>UWAGA:</strong> Nie przyznaje się 1 pkt.</blockquote>\n<h4>Typowe pułapki</h4>\n<ul><li><strong>Mylenie sensu pionowej osi symetrii</strong> - to symetria LEWO-PRAWO (kolumna i = kolumna 321-i), a nie góra-dół.</li><li><strong>&quot;Najmniejsza liczba wierszy do usunięcia&quot;</strong> - to po prostu liczba wierszy NIE-palindromowych (każdy taki MUSI być usunięty, palindromowe MOGĄ zostać).</li><li><strong>Indeksowanie 1 320 vs 0 319</strong> - w Python od 0, w pseudokodzie CKE od 1. <code>wiersz[i] vs wiersz[321-i]</code> jeśli indeksujemy od 1, a <code>wiersz[i] vs wiersz[319-i]</code> od 0.</li><li><strong>Tylko połowa porównań wystarczy</strong> - sprawdzaj <code>i</code> od 0 do n/2-1 (lub do n//2). Sprawdzanie wszystkich par jest podwójną pracą.</li><li><strong>Pomylenie z liczbą wierszy POZOSTAŁYCH</strong> - pytanie o USUNIĘTE (149), nie zachowane (51 = 200 - 149).</li></ul>\n<h4>Złożoność obliczeniowa</h4>\n<ul><li>Wczytanie: O(n × m) = O(64 000).</li><li>Sprawdzenie palindromu per wiersz: O(m/2) = O(160) = O(m).</li><li><strong>Całkowita: O(n × m) = O(64 000)</strong>, liniowa względem rozmiaru obrazu.</li></ul>"}]}