Przeczytaj
Algorytm sortowania szybkiego
Sortowanie szybkie polega na wybraniu elementu rozdzielającego (tzw. pivotpivot) oraz podzieleniu tablicy zawierającej dane na dwie części. W jednej zostają umieszczone elementy o wartościach większych niż pivot, w drugiej zaś — elementy o wartościach od niego mniejszych. Następnie elementy mniejsze i większe sortowane są osobno według tej samej zasady. Sortowanie odbywa się rekurencyjnierekurencyjnie do momentu, gdy każda z podtablic zostanie uporządkowana. Dokładne omówienie algorytmu sortowania szybkiego zostało przedstawione w e‑materiale Sortowanie szybkieSortowanie szybkie.
Zadanie 1. Wystawa obrazów
W pewnym muzeum organizowana jest wystawa obrazów poświęconych figurom geometrycznym. Okoliczne muzea wypożyczyły placówce części własnych ekspozycji pasujących do tematyki wystawy.
Zadanie 1.1
Muzeum chce ustalić, w którym roku powstało najwięcej dzieł z obecnej wystawy. Obrazy te zostaną oprawione w złote ramy.
Plik lata.txt
zawiera 76 wierszy zawierających rok powstania poszczególnych obrazów pokazywanych na wystawie (każdy rok zapisano w osobnym wierszu).
Napisz program, który wyznaczy rok, z którego pochodzi najwięcej dzieł, oraz wskaże, ile złotych ram na obrazy z tego roku powinno przygotować muzeum. Przyjmij, że jest tylko jeden rok z maksymalną liczbą powstałych dzieł. Zapisz obie wartości do pliku ramy.txt
.
Do oceny oddajesz:
plik
ramy.txt
zawierający odpowiedź (rok, w którym powstało najwięcej prezentowanych obrazów, oraz liczbę złotych ram potrzebnych do ich oprawienia)plik(i) z komputerową realizacją zadania (kodem programu)
Przedstaw rozwiązanie zadania w postaci programu w wybranym języku (C++, Java lub Python). Zadbaj o prawidłowe wczytanie i zapisanie danych z/do pliku tekstowego. Odpowiedź do zadania znajdziesz w osobnym pliku umieszczonym pod omówieniem pseudokodu.
Rozwiązanie
Rozwiązanie zadania przedstawimy w postaci pseudokodu, ponieważ na egzaminie maturalnym można korzystać z wybranego języka programowania: C++, Java lub Python.
W celu łatwiejszego zliczenia obrazów pochodzących z danego roku, posortujemy dane z pliku. Użyjemy do tego algorytmu sortowania szybkiego.
W przedstawionym algorytmie jako punkt rozdzielający przyjmuje się ostatnią wartość w tablicy.
Definiujemy funkcję, która będzie dzielić tablicę na dwie części, a następnie sortować je osobno. [linia 1]
Sprawdzamy, czy tablica, którą mamy podzielić, nie jest jednoelementowa (jeżeli jest, indeksyindeksy
lewy
iprawy
są sobie równe). [linia 2]Wyznaczamy punkt podziału (pivot); jednocześnie zapisujemy dane w tablicy z uwzględnieniem punktu podziału. [linia 3]
Rekurencyjnie uruchamiamy funkcję podziału dla utworzonych podtablic. [linie 4, 5]
Definiujemy funkcję podziału, która będzie ustawiać wartości mniejsze niż pivot po lewej stronie tablicy, zaś wartości większe - po prawej; następnie funkcja zwróci pozycję wartości rozdzielającej tablicę. [linia 1]
Ustawiamy pozycję elementu rozdzielającego oraz wartość zmiennej
mniejsza
. Pamiętajmy o tym, że przed zamianą pozycji komórek (w linii 7) dokonujemy inkrementacjiinkrementacji wartości zmiennejmniejsza
, a zatem musimy nadać jej wartość o 1 mniejszą od pierwszej sprawdzanej pozycji. [linie 2, 3]Inicjujemy pętlę, w której wartość
większa
będzie odpowiadać kolejnym indeksom tabeli. [linia 4]Sprawdzamy w każdej iteracji pętliiteracji pętli, czy wartość w tablicy dla indeksu
większa
ma wartość mniejszą niż pivot. Jeżeli tak, inkrementujemy wartość zmiennejmniejsza
, a następnie zamieniamy miejscami komórkikomórki o indeksachwiększa
imniejsza
. [linie od 5 do 7]Wstawiamy pivot w odpowiednie miejsce w tablicy — tak, by wszystkie elementy po lewej stronie były od niego mniejsze, a wszystkie po prawej — większe. [linia 8]
Zwracamy pozycję pivota i kończymy działanie funkcji. [linia 9]
Przejdźmy do właściwej części zadania. Na początku wczytujemy i sortujemy dane. Następnie zapisujemy algorytm, który przeszukuje posortowaną tablicę, by znaleźć rok powstania największej liczby obrazów oraz wskazać liczbę potrzebnych do ich oprawienia złotych ram:
Wczytujemy dane z pliku. [linia 1]
Wywołujemy funkcję, w której został zaimplementowany algorytm sortowania szybkiego. Jako dane wejściowe podajemy: tablicę lat, pozycję, od której należy rozpocząć sortowanie, oraz pozycję końcową. Tablice indeksujemy od zera, zgodnie z ich reprezentacją w komputerze. [linia 2]
Deklarujemy potrzebne zmienne. [linie 4‑7]
Korzystając z pętli, sprawdzamy poniższe warunki dla każdego roku:
jeżeli jest taki sam jak poprzednio rozpatrywany, dodajemy jedno wystąpienie do licznika wystąpień; [linia 11]
jeżeli jest inny niż poprzednio rozpatrywany, zapisujemy nowy rok jako aktualnie rozpatrywany i ustawiamy licznik wystąpień na 1. [linie 13‑14]
Z każdą iteracją pętli sprawdzamy również, czy dany rok pojawia się najwięcej razy. Jeżeli tak, zapisujemy ten rok i liczbę jego wystąpień w odpowiednich zmiennych. [linie 16‑18]
Na koniec zapisujemy wyniki do odpowiedniego pliku. [linie 20‑21]
Odpowiedź do zadania dla danych zapisanych w pliku tekstowym lata.txt
:
Zadanie 1.2
Po zakończeniu wystawy trzeba przygotować eksponaty do zwrócenia muzeom, z których zostały wypożyczone. Sporządzono w tym celu listę — numer każdego jej wiersza oznacza pozycję obrazu na wystawie, zaś w wierszu zapisany jest sześciocyfrowy kod z oznaczeniem danego muzeum i obrazu:
cyfry na pozycjach od do (od lewej strony) oznaczają numer muzeum,
cyfry na pozycjach od do to oznaczenie obrazu w danym muzeum.
Im większa jest liczba stanowiąca numer muzeum, tym dalej się ono znajduje. Obrazy należy ułożyć w takiej kolejności, aby najpierw zostały wysłane dzieła należące do najbardziej odległych muzeów. W rezultacie wszystkie eksponaty wrócą na swoje miejsce w podobnym czasie. Przyjmijmy, że z każdego muzeum wypożyczono tylko jeden obraz.
Plik lista.txt
zawiera 76 liczb (każda zapisana w osobnym wierszu), stanowiących numery poszczególnych dzieł. Numery te się nie powtarzają.
Napisz program, który uporządkuje obrazy w kolejności ich wysyłki oraz zapisze numery muzeów, do których wysyłane są obrazy, w pliku kolejność.txt
.
Dla danych wejściowych:
- przykładowy zapis do pliku wynikowego będzie wyglądał następująco:
Do oceny oddajesz:
plik
kolejność.txt
zawierający odpowiedź (liczby całkowite dodatnie będące numerami muzeów w odpowiedniej kolejności)plik(i) z komputerową realizacją zadania (kodem programu)
Przedstaw rozwiązanie zadania w postaci programu w wybranym języku (C++, Java lub Python). Zadbaj o prawidłowe wczytanie danych z pliku tekstowego do programu. Odpowiedź do zadania znajdziesz w osobnym pliku umieszczonym pod omówieniem pseudokodu.
Rozwiązanie
Rozwiązanie przedstawimy w postaci pseudokodu, ponieważ na egzaminie maturalnym można korzystać z języków C++, Java lub Python.
Aby rozwiązać zadanie, musimy nieco zmienić kod, który przedstawiliśmy w podpunkcie 1.
W celu zmiany porządku sortowania na nierosnący należy zmodyfikować funkcję podział()
, ponieważ to ona odpowiada za dzielenie elementów na podtablice mniejszych i większych elementów.
W pseudokodzie tablica Lata
została zastąpiona tablicą Kod
.
Modyfikujemy wyrażenie warunkowe; sprawdzamy, czy liczba na pozycji wskazywanej przez indeks
większa
jest większa niż element rozdzielający. Jeżeli tak, postępujemy dalej tak samo jak w poprzednim zadaniu. [linia 5]
Po posortowaniu musimy dodatkowo umieścić trzy pierwsze cyfry każdego kodu w tablicy pomocniczej, którą zapiszemy w pliku kolejność.txt
.
Po posortowaniu danych z pliku
lista.txt
umieszczamy kod każdego muzeum w tablicy pomocniczej. Korzystamy w tym celu z pomocniczej funkcjikod_muzuem()
zdefiniowanej poniżej. [linie 4, 5, 6]Zapisujemy kody poszczególnych muzeów w pliku
kolejność.txt
i kończymy działanie programu. [linia 8]
Definiujemy funkcję, która będzie przekształcać sześciocyfrowy kod w liczbę trzycyfrową, złożoną z trzech pierwszych cyfr kodu. [linia 1]
Kod dzielimy całkowicie przez tysiąc — pozbywamy się w ten sposób trzech ostatnich cyfr (pozostaje liczba trzycyfrowa). [linia 2]
Zwracamy wartość zmiennej
kod
. [linia 3]
Odpowiedź do zadania dla danych zapisanych w pliku tekstowym lista.txt
:
W pseudokodzie wykorzystaliśmy operator div
, który jest operatorem dzielenia całkowitego.
W zadaniach maturalnych polegających na pisaniu programu w wybranym języku programowania zdający może stosować funkcje wbudowane wybranego przez siebie języka. Dla funkcji zwracającej posortowaną tablicę liczb całkowitych tab
o długości n
są to odpowiednio:
C++
Java
Python
Słownik
numer (pozycja) komórki w tablicy
zwiększenie wartości zmiennej o jeden
inaczej: cykl pętli; pojedyncze wykonanie instrukcji zapisanych w pętli
kontener służący do przechowywania pojedynczego elementu tablicy
element sortowanej tablicy wybierany według określonego schematu (może to być np. element środkowy), ze względu na który tablica rozdzielana jest na podtablice - po lewej stronie tego elementu znajdują się wartości nie większe od pivota, a po prawej nie mniejsze od niego
technika programowania polegająca na odwoływaniu się procedur lub funkcji do samych siebie, aż do momentu spełnienia warunku podstawowego