{"id":"informator-maturalny-informatyka-2015/zad/21","paper_id":"informator-maturalny-informatyka-2015","number":"21","points":null,"ptype":"open","subject":"informatyka","category":"informator-maturalny","year":2015,"month":null,"level":null,"text":"Zadanie 21. Podzielność (0-10)\nW trzech plikach tekstowych liczby1.txt, liczby2.txt i liczby3.txt zapisano\npo 1000 dodatnich liczb binarnych. W każdym pliku liczby zapisano w kolejnych wierszach\npo jednej liczbie w wierszu. W pliku liczby1.txt długość zapisu każdej z liczb jest nie\nwiększa od 12. W pliku liczby2.txt długość zapisu każdej z liczb jest nie większa od 30,\nzaś w pliku liczby3.txt długość zapisu każdej liczby nie przekracza 200.\nDla każdego z plików z danymi wyznacz, ile zawiera on\n- liczb podzielnych przez 2,\n- liczb podzielnych przez 3,\n- liczb podzielnych przez 5.\nPrzykład:\nW pliku z 3 liczbami binarnymi:\n10101\n1100\n1110\nsą 2 liczby podzielne przez 2, 1 liczba podzielna przez 3 i 1 liczba podzielna przez 5.\nDo oceny oddajesz plik(i) o nazwie zawierający\ntu wpisz nazwę pliku/plików\nkomputerową realizację Twoich obliczeń oraz plik tekstowy podzielnosc.txt\nzawierający w dziewięciu kolejnych wierszach dziewięć liczb, po jednej w wierszu. Pierwsze\ntrzy wiersze powinny zawierać liczby liczb z pliku liczby1.txt podzielnych odpowiednio\nprzez 2, 3 i 5. Kolejne trzy wiersze powinny zawierać liczby liczb z pliku liczby2.txt\npodzielnych odpowiednio przez 2, 3 i 5, a ostatnie trzy wiersze liczby liczb z pliku\nliczby3.txt podzielnych odpowiednio przez 2, 3 i 5.\nWymagania ogólne\nIII. Rozwiązywanie problemów i podejmowanie\ndecyzji z wykorzystaniem komputera, z zastosowaniem\npodejścia algorytmicznego.\nWymagania szczegółowe\n5. Rozwiązywanie problemów i podejmowanie decyzji\nz wykorzystaniem komputera, stosowanie podejścia\nalgorytmicznego.\nZdający:\n1) analizuje, modeluje i rozwiązuje sytuacje\nproblemowe z różnych dziedzin,\n11) opisuje podstawowe algorytmy i stosuje algorytmy\nna liczbach całkowitych,\n12) projektuje rozwiązanie problemu (realizację\nalgorytmu) i dobiera odpowiednią strukturę danych,\n15) stosuje zasady programowania strukturalnego\ni modularnego do rozwiązywania problemu,\n23) stosuje podstawowe konstrukcje programistyczne\nw wybranym języku programowania, instrukcje\niteracyjne i warunkowe, rekurencję i procedury,\n72 Informator o egzaminie maturalnym z informatyki od roku szkolnego 2014/2015\ninstrukcje wejścia i wyjścia, poprawnie tworzy\nstrukturę programu,\n24) dobiera najlepszy algorytm, odpowiednie\nstruktury danych i oprogramowanie do rozwiązania\npostawionego problemu,\n26) ocenia poprawność komputerowego rozwiązania\nna podstawie jego testowania.\nSchemat punktowania\nCzynność\nLiczba\npunktów\nza zadanie\nZa poprawne wyniki dla pliku 1 - 2 punkty.\nZa poprawne wyniki dla pliku 2 - 3 punkty.\nZa poprawne wyniki dla pliku 3 - 4 punkty.\n9\nZadanie 21. Podzielność (0-10) - rozwiązanie\nPliki z danymi, plik programu źródłowego oraz plik podzielnosc.txt zawierający\nodpowiedzi znajdują się w folderze PODZIELNOSC.\nKomentarz\nJedna z metod rozwiązania tego zadania mogła by polegać na przytoczeniu i wykorzystaniu\nwłasności podzielności liczb binarnych. O ile własność podzielności przez 2 jest oczywista\ni powszechnie znana - najmniej znaczącą cyfrą takiej liczby musi być 0 - to już własności\npodzielności liczby binarnych przez inne liczby nie są tak naturalne i znane. Dla każdego\ndzielnika taka własność byłaby pewnie inna i prowadziłaby do algorytmu właściwego tylko\ndla tej własności. Przedstawimy algorytm, który jest jednakowy dla wszystkich dzielników\nz dokładnością do parametru, którym jest właśnie dzielnik.\nJest naturalne rozwiązanie, które pozwala stwierdzić, czy dana, dodatnia liczba binarna b,\njest podzielna całkowicie przez dodatnią (dziesiętną) liczbę całkowitą p. Wystarczy obliczyć\n(dziesiętną) wartość d liczby b i sprawdzić, czy p dzieli całkowicie d. W tym celu\nwykorzystujemy dostępny w większości języków programowania operator mod obliczania\nreszty z dzielenia liczb całkowitych i sprawdzamy, czy d mod p = 0. Do zamiany liczby\nbinarnej b na jej odpowiednik dziesiętny d można zastosować schemat Hornera. Prawda\njakie to proste? Jest tylko jeden mały problem. W kolejnych plikach z danymi są coraz\nwiększe liczby. W pliku liczby1.txt długość zapisu każdej z liczb jest nie większa niż 12\ni do zapisu każdej takiej liczby wystarczają dwa bajty, do zapisu jednej liczby z pliku\nliczby2.txt potrzeba już 4 bajtów, natomiast do zapisu liczby z pliku liczby3.txt\nmoże być potrzebnych 25 bajtów na każdą z nich. Jeśli język programowania użyty do\nrozwiązania pozwala reprezentować tak duże liczby i umożliwia wykonywanie na nich\npodstawowych arytmetycznych - dodawanie, mnożenie i branie modulo - to powyżej opisane\nrozwiązanie jest wystarczające. Często jednak języki programowania nie umożliwiają\nbezpośredniego operowania na bardzo dużych liczbach. Wówczas pozostaje albo\nzaprogramować własną arytmetykę dużych liczb, albo, jak w tym przypadku, skorzystać\nz pewnych własności używanych operacji arytmetycznych. Tutaj skorzystamy z własności\noperacji modulo brania reszty z dzielenia, które to własności pozwalają nam operować tylko\nna resztach z dzielenia przez dzielnik p, a nie na całych liczbach. Każda taka reszta jest nie\nwiększa od p. Dwie podstawowe, wykorzystywane przez nas własności są następujące:\nPrzykładowe zadania z rozwiązaniami 73\nDla dodatnich liczb całkowitych a, b i p mamy:\n(1) (a + b) mod p =( a mod p + b mod p) mod p\n(2) (a*b) mod p = ((a mod p) * (b mod p)) mod p\nTak więc do policzenia reszty z dzielenia przez p dodatniej liczby całkowitej d, której wartość\njest taka sama jak wartość liczby binarnej b, należy po prostu zastosować schemat Hornera\nobliczania wartości d z zapisu b pamiętając, żeby wszystkie obliczenia wykonywać modulo p.\nOto funkcja zapisana w języku programowania C++, która dla liczby binarnej b podanej\nw postaci zero-jedynkowego napisu i dodatniego, całkowitego podzielnika p, oblicza resztę\nz dzielenia wartości dziesiętnej liczby b przez p.\nint Reszta(string b, int p){\nconst char zero = '0';\nint dl = b.length(); //obliczenie długości zapisu liczby b\nint d = 0; // po zakończeniu obliczeń wartością d będzie\n// wartość dziesiętna liczby b modulo p\n// schemat Hornera modulo p\nfor (int j = 0; j < dl; j++){\nint cyfra = b[j] - zero;//odzyskanie kolejnej cyfry liczby b\n// poczynając od najbardziej znaczącej\nd = (d*2 + cyfra) % p; // % jest operatorem modulo w C++\n}\nreturn d;\n}\nNależy zwrócić jeszcze uwagę na drobiazg, jakim jest odzyskiwanie wartości liczbowych\nkolejnych cyfr zapisu liczby b. Liczba b jest zadana jako napis złożony ze znaków ‘0’ i ‘1’.\nKażdy ze znaków ‘0’ lub ‘1’ do obliczeń arytmetycznych należy zamienić odpowiednio na\nliczbę 0 lub 1. Do tego celu najprościej wykorzystać fakt, że cyfry ‘0’, ‘1’, …, ‘9’ są\nkodowane kolejnymi liczbami naturalnymi poczynając od kodu znaku ‘0’. Tak więc, gdy od\nkodu cyfry odejmiemy kod cyfry ‘0’, to otrzymamy liczbę odpowiadającą tej cyfrze.\nW przedstawionym powyżej rozwiązaniu wykorzystujemy ten fakt - wartość wyrażenia b[j]\n- zero jest obliczana z wykorzystaniem kodów cyfr b[j] i zero.\nPoniżej przedstawiamy program Podzielnosc zapisany w języku C++, który oblicza\nżądane wyniki dla jednego pliku. Dla przykładu, żeby uzyskać wyniki dla pliku\nliczby1.txt można program wykonywalny Podzielnosc uruchomić w katalogu\nzawierającym plik liczby1.txt następującą komendą z wiersza poleceń:\nPodzielnosc < liczby1.txt > wyniki1.txt\nWyniki znajdą się w pliku tekstowym wyniki1.txt w tym samym katalogu. Na koniec\ntrzeba pamiętać, żeby wyniki obliczeń dla wszystkich trzech plików umieścić w jednym pliku\ntekstowym podzielnosc.txt zgodnie z opisem w treści zadania.\n//Program Podzielnosc\n#include <iostream>\nusing namespace std;\nint Reszta(string b, int p){\nconst char zero = '0';\n74 Informator o egzaminie maturalnym z informatyki od roku szkolnego 2014/2015\nint dl = b.length(); //obliczenie długości zapisu liczby b\nint d = 0; //po zakończeniu obliczeń wartością d będzie\n// wartość dziesiętna liczby b modulo p\n// schemat Hornera modulo p\nfor (int j = 0; j < dl; j++){\nint cyfra = b[j] - zero; //odzyskanie kolejnej cyfry liczby\nb\n//poczynając od najbardziej znaczącej\nd = (d*2 + cyfra) % p; //% jest operatorem modulo w C++\n}\nreturn d;\n}\nint main(){\nstring liczba;\nconst int n = 1000; //rozmiar danych\nint podz_2 = 0, podz_3 = 0, podz_5 = 0; // podz_p - liczba\nliczb\n// podzielnych przez p\nfor (int i = 0; i < n; i++){\ncin >> liczba; //wczytanie kolejnej liczby;\nif (Reszta(liczba,2) == 0) podz_2++;\nif (Reszta(liczba,3) == 0) podz_3++;\nif (Reszta(liczba,5) == 0) podz_5++;\n}\ncout << \"podzielne przez \" << 2 << \" : \" << podz_2 << \"\\n\";\ncout << \"podzielne przez \" << 3 << \" : \" << podz_3 << \"\\n\";\ncout << \"podzielne przez \" << 5 << \" : \" << podz_5 << \"\\n\";\nreturn 0;\n}\nPrzykładowe zadania z rozwiązaniami 75","answer":null,"answer_text":null,"solution":null,"image":"img/informator-maturalny-informatyka-2015/zad-21.webp","solution_image":null,"topics":null,"page_from":71,"source":"ocr","answer_source":null,"answer_text_source":null,"solution_source":null,"text_source":"ocr","source_label":"Informatyka · Informator maturalny · 2015","subject_label":"Informatyka","category_label":"Informator maturalny","text_html":"<p>Zadanie 21. Podzielność (0-10)<br>W trzech plikach tekstowych liczby1.txt, liczby2.txt i liczby3.txt zapisano<br>po 1000 dodatnich liczb binarnych. W każdym pliku liczby zapisano w kolejnych wierszach<br>po jednej liczbie w wierszu. W pliku liczby1.txt długość zapisu każdej z liczb jest nie<br>większa od 12. W pliku liczby2.txt długość zapisu każdej z liczb jest nie większa od 30,<br>zaś w pliku liczby3.txt długość zapisu każdej liczby nie przekracza 200.<br>Dla każdego z plików z danymi wyznacz, ile zawiera on</p>\n<ul><li>liczb podzielnych przez 2,</li><li>liczb podzielnych przez 3,</li><li>liczb podzielnych przez 5.</li></ul>\n<p>Przykład:<br>W pliku z 3 liczbami binarnymi:<br>10101<br>1100<br>1110<br>są 2 liczby podzielne przez 2, 1 liczba podzielna przez 3 i 1 liczba podzielna przez 5.<br>Do oceny oddajesz plik(i) o nazwie zawierający<br>tu wpisz nazwę pliku/plików<br>komputerową realizację Twoich obliczeń oraz plik tekstowy podzielnosc.txt<br>zawierający w dziewięciu kolejnych wierszach dziewięć liczb, po jednej w wierszu. Pierwsze<br>trzy wiersze powinny zawierać liczby liczb z pliku liczby1.txt podzielnych odpowiednio<br>przez 2, 3 i 5. Kolejne trzy wiersze powinny zawierać liczby liczb z pliku liczby2.txt<br>podzielnych odpowiednio przez 2, 3 i 5, a ostatnie trzy wiersze liczby liczb z pliku<br>liczby3.txt podzielnych odpowiednio przez 2, 3 i 5.<br>Wymagania ogólne<br>III. Rozwiązywanie problemów i podejmowanie<br>decyzji z wykorzystaniem komputera, z zastosowaniem<br>podejścia algorytmicznego.<br>Wymagania szczegółowe</p>\n<ol><li>Rozwiązywanie problemów i podejmowanie decyzji</li></ol>\n<p>z wykorzystaniem komputera, stosowanie podejścia<br>algorytmicznego.<br>Zdający:</p>\n<ol><li>analizuje, modeluje i rozwiązuje sytuacje</li></ol>\n<p>problemowe z różnych dziedzin,</p>\n<ol><li>opisuje podstawowe algorytmy i stosuje algorytmy</li></ol>\n<p>na liczbach całkowitych,</p>\n<ol><li>projektuje rozwiązanie problemu (realizację</li></ol>\n<p>algorytmu) i dobiera odpowiednią strukturę danych,</p>\n<ol><li>stosuje zasady programowania strukturalnego</li></ol>\n<p>i modularnego do rozwiązywania problemu,</p>\n<ol><li>stosuje podstawowe konstrukcje programistyczne</li></ol>\n<p>w wybranym języku programowania, instrukcje<br>iteracyjne i warunkowe, rekurencję i procedury,<br>72 Informator o egzaminie maturalnym z informatyki od roku szkolnego 2014/2015<br>instrukcje wejścia i wyjścia, poprawnie tworzy<br>strukturę programu,</p>\n<ol><li>dobiera najlepszy algorytm, odpowiednie</li></ol>\n<p>struktury danych i oprogramowanie do rozwiązania<br>postawionego problemu,</p>\n<ol><li>ocenia poprawność komputerowego rozwiązania</li></ol>\n<p>na podstawie jego testowania.<br>Schemat punktowania<br>Czynność<br>Liczba<br>punktów<br>za zadanie<br>Za poprawne wyniki dla pliku 1 - 2 punkty.<br>Za poprawne wyniki dla pliku 2 - 3 punkty.<br>Za poprawne wyniki dla pliku 3 - 4 punkty.<br>9<br>Zadanie 21. Podzielność (0-10) - rozwiązanie<br>Pliki z danymi, plik programu źródłowego oraz plik podzielnosc.txt zawierający<br>odpowiedzi znajdują się w folderze PODZIELNOSC.<br>Komentarz<br>Jedna z metod rozwiązania tego zadania mogła by polegać na przytoczeniu i wykorzystaniu<br>własności podzielności liczb binarnych. O ile własność podzielności przez 2 jest oczywista<br>i powszechnie znana - najmniej znaczącą cyfrą takiej liczby musi być 0 - to już własności<br>podzielności liczby binarnych przez inne liczby nie są tak naturalne i znane. Dla każdego<br>dzielnika taka własność byłaby pewnie inna i prowadziłaby do algorytmu właściwego tylko<br>dla tej własności. Przedstawimy algorytm, który jest jednakowy dla wszystkich dzielników<br>z dokładnością do parametru, którym jest właśnie dzielnik.<br>Jest naturalne rozwiązanie, które pozwala stwierdzić, czy dana, dodatnia liczba binarna b,<br>jest podzielna całkowicie przez dodatnią (dziesiętną) liczbę całkowitą p. Wystarczy obliczyć<br>(dziesiętną) wartość d liczby b i sprawdzić, czy p dzieli całkowicie d. W tym celu<br>wykorzystujemy dostępny w większości języków programowania operator mod obliczania<br>reszty z dzielenia liczb całkowitych i sprawdzamy, czy d mod p = 0. Do zamiany liczby<br>binarnej b na jej odpowiednik dziesiętny d można zastosować schemat Hornera. Prawda<br>jakie to proste? Jest tylko jeden mały problem. W kolejnych plikach z danymi są coraz<br>większe liczby. W pliku liczby1.txt długość zapisu każdej z liczb jest nie większa niż 12<br>i do zapisu każdej takiej liczby wystarczają dwa bajty, do zapisu jednej liczby z pliku<br>liczby2.txt potrzeba już 4 bajtów, natomiast do zapisu liczby z pliku liczby3.txt<br>może być potrzebnych 25 bajtów na każdą z nich. Jeśli język programowania użyty do<br>rozwiązania pozwala reprezentować tak duże liczby i umożliwia wykonywanie na nich<br>podstawowych arytmetycznych - dodawanie, mnożenie i branie modulo - to powyżej opisane<br>rozwiązanie jest wystarczające. Często jednak języki programowania nie umożliwiają<br>bezpośredniego operowania na bardzo dużych liczbach. Wówczas pozostaje albo<br>zaprogramować własną arytmetykę dużych liczb, albo, jak w tym przypadku, skorzystać<br>z pewnych własności używanych operacji arytmetycznych. Tutaj skorzystamy z własności<br>operacji modulo brania reszty z dzielenia, które to własności pozwalają nam operować tylko<br>na resztach z dzielenia przez dzielnik p, a nie na całych liczbach. Każda taka reszta jest nie<br>większa od p. Dwie podstawowe, wykorzystywane przez nas własności są następujące:<br>Przykładowe zadania z rozwiązaniami 73<br>Dla dodatnich liczb całkowitych a, b i p mamy:<br>(1) (a + b) mod p =( a mod p + b mod p) mod p<br>(2) (a*b) mod p = ((a mod p) * (b mod p)) mod p<br>Tak więc do policzenia reszty z dzielenia przez p dodatniej liczby całkowitej d, której wartość<br>jest taka sama jak wartość liczby binarnej b, należy po prostu zastosować schemat Hornera<br>obliczania wartości d z zapisu b pamiętając, żeby wszystkie obliczenia wykonywać modulo p.<br>Oto funkcja zapisana w języku programowania C++, która dla liczby binarnej b podanej<br>w postaci zero-jedynkowego napisu i dodatniego, całkowitego podzielnika p, oblicza resztę<br>z dzielenia wartości dziesiętnej liczby b przez p.<br>int Reszta(string b, int p){<br>const char zero = &#x27;0&#x27;;<br>int dl = b.length(); //obliczenie długości zapisu liczby b<br>int d = 0; // po zakończeniu obliczeń wartością d będzie<br>// wartość dziesiętna liczby b modulo p<br>// schemat Hornera modulo p<br>for (int j = 0; j &lt; dl; j++){<br>int cyfra = b[j] - zero;//odzyskanie kolejnej cyfry liczby b<br>// poczynając od najbardziej znaczącej<br>d = (d*2 + cyfra) % p; // % jest operatorem modulo w C++<br>}<br>return d;<br>}<br>Należy zwrócić jeszcze uwagę na drobiazg, jakim jest odzyskiwanie wartości liczbowych<br>kolejnych cyfr zapisu liczby b. Liczba b jest zadana jako napis złożony ze znaków ‘0’ i ‘1’.<br>Każdy ze znaków ‘0’ lub ‘1’ do obliczeń arytmetycznych należy zamienić odpowiednio na<br>liczbę 0 lub 1. Do tego celu najprościej wykorzystać fakt, że cyfry ‘0’, ‘1’, …, ‘9’ są<br>kodowane kolejnymi liczbami naturalnymi poczynając od kodu znaku ‘0’. Tak więc, gdy od<br>kodu cyfry odejmiemy kod cyfry ‘0’, to otrzymamy liczbę odpowiadającą tej cyfrze.<br>W przedstawionym powyżej rozwiązaniu wykorzystujemy ten fakt - wartość wyrażenia b[j]</p>\n<ul><li>zero jest obliczana z wykorzystaniem kodów cyfr b[j] i zero.</li></ul>\n<p>Poniżej przedstawiamy program Podzielnosc zapisany w języku C++, który oblicza<br>żądane wyniki dla jednego pliku. Dla przykładu, żeby uzyskać wyniki dla pliku<br>liczby1.txt można program wykonywalny Podzielnosc uruchomić w katalogu<br>zawierającym plik liczby1.txt następującą komendą z wiersza poleceń:<br>Podzielnosc &lt; liczby1.txt &gt; wyniki1.txt<br>Wyniki znajdą się w pliku tekstowym wyniki1.txt w tym samym katalogu. Na koniec<br>trzeba pamiętać, żeby wyniki obliczeń dla wszystkich trzech plików umieścić w jednym pliku<br>tekstowym podzielnosc.txt zgodnie z opisem w treści zadania.<br>//Program Podzielnosc<br>#include &lt;iostream&gt;<br>using namespace std;<br>int Reszta(string b, int p){<br>const char zero = &#x27;0&#x27;;<br>74 Informator o egzaminie maturalnym z informatyki od roku szkolnego 2014/2015<br>int dl = b.length(); //obliczenie długości zapisu liczby b<br>int d = 0; //po zakończeniu obliczeń wartością d będzie<br>// wartość dziesiętna liczby b modulo p<br>// schemat Hornera modulo p<br>for (int j = 0; j &lt; dl; j++){<br>int cyfra = b[j] - zero; //odzyskanie kolejnej cyfry liczby<br>b<br>//poczynając od najbardziej znaczącej<br>d = (d*2 + cyfra) % p; //% jest operatorem modulo w C++<br>}<br>return d;<br>}<br>int main(){<br>string liczba;<br>const int n = 1000; //rozmiar danych<br>int podz_2 = 0, podz_3 = 0, podz_5 = 0; // podz_p - liczba<br>liczb<br>// podzielnych przez p<br>for (int i = 0; i &lt; n; i++){<br>cin &gt;&gt; liczba; //wczytanie kolejnej liczby;<br>if (Reszta(liczba,2) == 0) podz_2++;<br>if (Reszta(liczba,3) == 0) podz_3++;<br>if (Reszta(liczba,5) == 0) podz_5++;<br>}<br>cout &lt;&lt; &quot;podzielne przez &quot; &lt;&lt; 2 &lt;&lt; &quot; : &quot; &lt;&lt; podz_2 &lt;&lt; &quot;\\n&quot;;<br>cout &lt;&lt; &quot;podzielne przez &quot; &lt;&lt; 3 &lt;&lt; &quot; : &quot; &lt;&lt; podz_3 &lt;&lt; &quot;\\n&quot;;<br>cout &lt;&lt; &quot;podzielne przez &quot; &lt;&lt; 5 &lt;&lt; &quot; : &quot; &lt;&lt; podz_5 &lt;&lt; &quot;\\n&quot;;<br>return 0;<br>}<br>Przykładowe zadania z rozwiązaniami 75</p>","solutions":[]}