- 6 grudnia 2024
- Posted by: Damian
- Category: Baza wiedzy

W poniższym artykule znajdziesz rozwiązania majowej matury z informatyki z roku 2022. Wykorzystano w tym celu Microsoft Access (SQL) i Excel z pakietu Office oraz języki programowania C++, java i python. Załączniki potrzebne do tych zadań znajdziesz pod tym linkiem.
Zadanie 1 – n-permutacja

Na początek krótkie zadanie z teorii, wystarczy sprawdzić, czy w ciągu są umieszczone wszystkie liczby z danego zakresu [1,n], gdzie n to długość ciągu i czy występują w nim tylko raz.
Zadanie 1.1.

- n = 3 – (1, 3, 1) – wystarczy podmienić jedną z jedynek na 2.
- n = 4 – (1, 4, 2, 5) – Wystarczy zamienić 5 na 3, bo wszystkie pozostałe liczby są umieszczone w ciągu tylko raz i mieszczą się w zakresie [1,n]. Liczba elementów do podmiany wynosi więc 1.
- n = 5 – (2, 2, 2, 2, 2) – Należy podmienić występującą cztery razy liczbę 2, bo każdy element powinien pojawiać się tylko raz. Do trzeciego wiersza wpisujemy 4.
- n = 4 – (4, 3, 2, 1) – W tym wierszu nic nie trzeba zmieniać. Wpisujemy więc 0.
- n = 6 – (5, 4, 1, 5, 6, 8) – Liczba 8 jest spoza zakresu (bo n = 6), a 5 występuje 2 razy, także je również trzeba na coś podmienić. Liczba elementów do podmiany to 2.
- n = 6 – (8, 4, 9, 6, 5, 7) – Liczby 7, 8, 9 są spoza zakresu, wpisujemy więc wartość 3.
Rozwiązanie:
n | ciąg | liczba elementów do podmiany |
---|---|---|
3 | (1,3,1) | 1 |
4 | (1,4,2,5) | 1 |
5 | (2,2,2,2,2) | 4 |
4 | (4,3,2,1) | 0 |
6 | (5,4,1,5,6,8) | 2 |
6 | (8,4,9,6,5,7) | 3 |
Zadanie 1.2.
1 2 3 4 5 6 7 8 9 10 11 12 | zliczacz[1...n] dla i=1,2...n wykonuj zliczacz[i] ← 0 dla 1,2...n wykonuj jeżeli A[i]<=n zliczacz[A[i]]←zliczacz[A[i]]+1 licznikDobrych←0 dla 1,2...n wykonuj jeżeli zliczacz[i]>0: licznikDobrych←licznikDobrych+1 k←n-licznikDobrych zwróć k i zakończ |
Poddajmy analizie powyższy algorytm.
Na początek tworzymy tablicę zliczacz, która jak nazwa wskazuje będzie zliczała w tym przypadku wystąpienia danych liczb. Przechodzimy po kolejnych wartościach używając pętli. Po sprawdzeniu czy dana liczba mieści się w tablicy, zwiększamy jej liczbę wystąpień. Mając już wystąpienia, wystarczy policzyć ile liczb ze zbioru pojawiło się przynajmniej jeden raz. Na koniec odejmujemy od długości zbioru, który powinniśmy mieć, zmienną licznikDobrych, która jest równa liczbie poprawnych elementów. Uzyskana wartość to nasz wynik.
Zadanie 2 – ab-słowo

W tym zadaniu CKE zastosowało bardzo dziwną notację, w której tablice indeksujemy od 0, ale stringi już od 1.
Po dokładnej analizie algorytmu, można dojść do wniosku, że na kolejnych pozycjach tablicy A znajdują się wartości odpowiadające ilości wystąpień “a” na lewo od danego indeksu.
Tablica B działa trochę inaczej, ponieważ również liczy litery, w tym przypadku “b”, ale liczy je od prawego do lewego końca w ciągu s. Pamiętajmy, że ze względu na wykonywanie pętli do 1, nigdy nie będzie ustalona wartość B[0], dlatego będziemy stosować w tym miejscu znak zapytania.
Obie tablice wliczają również literę na odpowiadającym indeksie (obecna komórka).
Ostatnia pętla po prostu znajduje wartość odpowiadającą pozycji, gdzie liczba “a” po lewej i “b” po prawej w ciągu s jest największa. Przykłady podano w kolejnym podpunkcie.
Zadanie 2.1.

Dla pierwszego przykładu wartość to 4, idąc od lewej po danym ciągu też dojdziemy do takiego wniosku. Zobaczmy jak wyglądałyby tablice A i B w takiej sytuacji. Pamiętajmy, że ze względu na zastosowanie linijki k ⬅ A[i] + B[i+1], w przykładzie wartości tablicy B, zaczynamy od znaku ?, bo do i dodajemy wartość 1.
A: 0, 1, 2, 2, 3, 3
B: ?, 2, 2, 2, 1, 1, 0
k: 2, 3, 4, 4, 4, 4
Idąc teraz po kolejnych wartościach widzimy, że maksymalne A[i] + B[i+1] jakie osiągniemy to 4, czyli nasza analiza jest trafna.
Przykład n = 6, s: aababb
A: 0, 1, 2, 2, 3, 3, 3
B: ?, 3, 3, 3, 2, 2, 1, 0
k: 3, 4, 5, 5, 5, 5, 5
k = 5 dla i = 2
Przykład n = 9, s: baabbaaab
A: 0, 0, 1, 2, 2, 2, 3, 4, 5, 5
B: ?, 4, 3, 3, 3, 2, 2, 2, 2, 1, 0
k: 4, 4, 4, 5, 5, 5, 5, 5, 6, 6
k = 6 dla i = 8
Rozwiązanie:
n | s | Wynik działania algorytmu (wartość k) |
---|---|---|
5 | aabab | 4 |
2 | ab | 2 |
3 | aaa | 3 |
6 | aababb | 5 |
9 | baabbaaab | 6 |
Zadanie 2.2.

Wiedząc jak działa algorytm, możemy w pierwszym wierszu wpisać np. aaaaabbbbb, wtedy dla i = 4, zmienna k przyjmuje wartość 10, bo ma po lewej i na swojej pozycji wartość pięć znaków a, z kolei po prawej ma pięć znaków b, co daje razem k = 10.
W drugim wierszu możemy wpisać bababababa, gdzie w tym ciągu wartość k jest w zasadzie stała i wynosi 5 ponieważ dla każdej wartości zmiennej i zwiększa się liczba znaków a, ale w tym samym zmniejsza się liczba znaków b.
Rozwiązanie:
n | s | Wynik działania algorytmu (wartość k) |
---|---|---|
10 | aaaaabbbbb | 10 |
10 | bababababa | 5 |
Zadanie 2.3.

Stan tablicy A w danych komórkach:
0 – 300: wartości kolejno od 0 do 300,
301 – 850: 300 (przez cały czas),
851 – 1150: od 301 do 600,
1151 – 1157: 600 (przez cały czas),
1158 – 1437: od 601 do 880,
1438 – 1547: 880 (przez cały czas),
Stan tablicy B w innych komórkach:
0: stan nie jest znany.
Na początek przekonajmy się ile wynosi suma wartości B (liczba liter b): 550+7+110=667.
1 – 300: 667 (przez cały czas),
301 – 850: od 667 do 118,
851 – 1150: 117 (przez cały czas),
1151 – 1157: od 117 do 111,
1158 – 1437: 110 (przez cały czas),
1438 – 1547: od 110 do 1,
1548: 0.
Teraz wystarczy sprawdzić wartości końcowe danego przedziału dla a i dodać wartość początku następnego przedziału dla b. Z uzyskanych wartości należy wybrać tę największą.
Rozwiązanie:
Zmienna k uzyska największą wartość dla i = 1437, gdzie wynosi 990.
Zadanie 3 – Test

Zadanie 3.1.

Zobaczmy ile razy wykona się s ← s + 1.
Pierwsza pętla wykona się n razy, jednak druga również jest zależna od n. Co prawda nie wykona się dla każdej pętli zewnętrznej n-razy, ale nadal jest od niej zależna, więc złożoność to n2. Generalnie widząc pętle w pętli odpowiedzią jest liczba zagnieżdżeń +1 (np. widząc jedno zagnieżdżenie, to n1+1, czyli n2, z kolei przy 4 zagnieżdżeniach to n4+1 czyli n5).
Rozwiązanie:
- Nie jest liniowa, bo jest kwadratowa – F,
- Tak, jest kwadratowa – P,
- Nie jest n log n, bo jest kwadratowa – F,
- Tak, ponieważ n2 < n3 – P.
Zadanie 3.2.

Liczby najlepiej zamienić na system binarny, ponieważ wszystkie wartości są podane w systemie o podstawie 2, więc nie ma potrzeby konwertowania na system dziesiętny. Możesz to zrobić jeśli w nim czujesz się najpewniej.
1324 = 111102
31114 = 110101012
W tym momencie z łatwością dodamy liczby ze sobą:
000111102 | |
+ | 110101012 |
Wynik | 111100112 |
Teraz można łatwo wynik 111100112 przekonwertować na inne systemy:
111100112 = 33034
111100112 = 3638
111100112 = F316
Rozwiązanie:
Odpowiedzi to FFPP.
Zadanie 3.3.

Rozwiązanie:
- Zapytanie zwraca sumy punktów z tabeli mandaty, należące do poszczególnych osób (korzysta się tu z id_osoby), zwracane są tylko osoby z liczbą punktów większą niż 5. Pierwsza osoba powinna mieć 21 pkt – F,
- Zapytanie zwraca id osób oraz sumy punktów, które dana osoba posiada – P,
- To zapytanie zwraca dla każdego wiersza osobną liczbę, nie sumuje wszystkiego w jedną liczbę – F,
- Zapytanie zwraca liczbę mandatów, których wartość wynosi 21 punktów – P.
Zadanie 4 – Liczby

Na początek części praktycznej dość standardowe zadanie z programowania. Najpierw oczywiście należy zaimportować plik:
Implementacja – Python
1 2 3 4 | with open("liczby.txt") as plik: linie = plik.readlines() for i in range(len(linie)): linie[i] = int(linie[i].rstrip()) |
Warto od razu przekonwertować tekst na liczby używając funkcji int(), wystarczy, że zrobimy to tylko raz i o tym nie zapomnimy.
Implementacja – C++
1 2 3 4 5 6 7 8 9 | ifstream plik("liczby.txt"); vector<int> linie; int liczba; // Wczytanie danych z pliku while (plik >> liczba) { linie.push_back(liczba); } plik.close(); |
Implementacja – Java
1 2 3 4 5 6 7 | try { BufferedReader plik = new BufferedReader(new FileReader("liczby.txt")); List<Integer> linie = plik.lines().map(Integer::parseInt).collect(Collectors.toList()); plik.close(); } catch (IOException e) { e.printStackTrace(); } |
Zadanie 4.1.

W pierwszym podpunkcie łatwiej będzie jednak działać na zmiennych typu string (napisy), bo możemy wtedy łatwo dostać się do konkretnych cyfr używając indeksacji. Zawsze można użyć mod (zwracanie reszty z dzielenia) i dzielenia całkowitego, żeby uzyskać odpowiednie cyfry jednak jest to dłuższe rozwiązanie.
Będziemy korzystać z dwóch zmiennych:
- licznik – ta zmienna określa jak wiele liczb spełnia warunek,
- pierwsza – ta zmienna określa pierwszą liczbę która spełnia warunek. Jako, że znamy zakres w jakim liczby występują wystarczy, że ustawimy początkową wartość na liczbę spoza tego zakresu. Wtedy wiemy czy została już ona zmieniona na pierwszą występującą w pliku (wtedy już będzie w zakresie). Moglibyśmy też użyć np. zmiennej czyBylaZmiana, ale nie ma takiej potrzeby.
Na koniec oczywiście wyświetlamy wartości tak jak proszą o to w zadaniu:
Implementacja – Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | with open("liczby.txt") as plik: linie = plik.readlines() for i in range(len(linie)): linie[i] = int(linie[i].rstrip()) licznik = 0 pierwsza = 0 for liczba in linie: liczba = str(liczba) if liczba[0] == liczba[-1]: licznik += 1 if pierwsza == 0: pierwsza = liczba print(licznik,pierwsza) |
Implementacja – C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include <iostream> #include <fstream> #include <vector> #include <algorithm> #include <set> #include <map> using namespace std; int main() { ifstream plik("liczby.txt"); vector<int> linie; int liczba; // Wczytanie danych z pliku while (plik >> liczba) { linie.push_back(liczba); } plik.close(); // Zadanie 4.1 int licznik = 0; int pierwsza = 0; for (int liczba : linie) { string liczbaStr = to_string(liczba); if (liczbaStr[0] == liczbaStr.back()) { licznik++; if (pierwsza == 0) { pierwsza = liczba; } } } cout << licznik << " " << pierwsza << endl; return 0; } |
Implementacja – Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | import java.io.*; import java.util.*; import java.util.stream.Collectors; public class Main { // Funkcja zwracająca czynniki pierwsze liczby public static List<Integer> czynnikPierwsze(int liczba) { List<Integer> czynniki = new ArrayList<>(); for (int i = 2; i <= liczba; i++) { while (liczba % i == 0) { czynniki.add(i); liczba /= i; } if (liczba == 1) break; } return czynniki; } public static void main(String[] args) { try { BufferedReader plik = new BufferedReader(new FileReader("liczby.txt")); List<Integer> linie = plik.lines().map(Integer::parseInt).collect(Collectors.toList()); plik.close(); // Zadanie 4.1 int licznik = 0; int pierwsza = 0; for (int liczba : linie) { String liczbaStr = Integer.toString(liczba); if (liczbaStr.charAt(0) == liczbaStr.charAt(liczbaStr.length() - 1)) { licznik++; if (pierwsza == 0) { pierwsza = liczba; } } } System.out.println(licznik + " " + pierwsza); } catch (IOException e) { e.printStackTrace(); } } } |
Rozwiązanie:
ile liczb: 18
pierwsza: 93639
Zadanie 4.2.

W drugim podpunkcie pojawia się dość standardowy i częsty na maturze problem – rozkład liczb na czynniki pierwsze. Przed rozpoczęciem warto napisać funkcję, która zwraca listę ze wszystkimi czynnikami.
Implementacja – Python
1 2 3 4 5 6 7 8 9 | def czynnikPierwsze(liczba): czynniki = [] for i in range(2,liczba+1): while liczba % i == 0: czynniki.append(i) liczba //= i if liczba == 1: break return czynniki |
Implementacja – C++
1 2 3 4 5 6 7 8 9 10 11 | vector<int> czynnikPierwsze(int liczba) { vector<int> czynniki; for (int i = 2; i <= liczba; i++) { while (liczba % i == 0) { czynniki.push_back(i); liczba /= i; } if (liczba == 1) break; // Przerwij, jeśli liczba osiągnęła 1 } return czynniki; } |
Implementacja – Java
1 2 3 4 5 6 7 8 9 10 11 | public static List<Integer> czynnikPierwsze(int liczba) { List<Integer> czynniki = new ArrayList<>(); for (int i = 2; i <= liczba; i++) { while (liczba % i == 0) { czynniki.add(i); liczba /= i; } if (liczba == 1) break; } return czynniki; } |
Dla każdej liczby od 2 do badanej liczby sprawdzamy, czy jest ona jej dzielnikiem. Jeśli ją dzieli to może okazać się, że dzieli ją wiele razy. Wtedy musimy sprawdzić ile razy i dodać ją odpowiednio dużo razy do listy czynniki, przy każdym dodaniu należy też badaną liczbę podzielić przez dany dzielnik. Inaczej przecież warunek będzie zawsze spełniony, a pętla nigdy się nie skończy. Gdy liczba jest równa jeden oznacza to, że nie ma już więcej dzielników i nie warto dalej ich szukać, dlatego przerywamy działanie pętli i zwracamy listę. Mając do dyspozycji naszą funkcję przechodzimy do dalszej części podpunktu:
Implementacja – Python
1 2 3 4 5 6 7 8 | maksCzynnikowLiczba = 0 maksRoznychLiczba = 0 for liczba in linie: if len(czynnikPierwsze(liczba)) > len(czynnikPierwsze(maksCzynnikowLiczba)): maksCzynnikowLiczba = liczba if len(set(czynnikPierwsze(liczba))) > len(set(czynnikPierwsze(maksRoznychLiczba))): maksRoznychLiczba = liczba print(maksCzynnikowLiczba,len(czynnikPierwsze(maksCzynnikowLiczba)),maksRoznychLiczba,len(set(czynnikPierwsze(maksRoznychLiczba)))) |
Implementacja – C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #include <iostream> #include <fstream> #include <vector> #include <algorithm> #include <set> #include <map> using namespace std; // Funkcja zwracająca czynniki pierwsze liczby vector<int> czynnikPierwsze(int liczba) { vector<int> czynniki; for (int i = 2; i <= liczba; i++) { while (liczba % i == 0) { czynniki.push_back(i); liczba /= i; } if (liczba == 1) break; // Przerwij, jeśli liczba osiągnęła 1 } return czynniki; } int main() { ifstream plik("liczby.txt"); vector<int> linie; int liczba; // Wczytanie danych z pliku while (plik >> liczba) { linie.push_back(liczba); } plik.close(); // Zadanie 4.2 int maksCzynnikowLiczba = 0; int maksRoznychLiczba = 0; for (int liczba : linie) { if (czynnikPierwsze(liczba).size() > czynnikPierwsze(maksCzynnikowLiczba).size()) { maksCzynnikowLiczba = liczba; } auto temp = czynnikPierwsze(liczba); auto temp2 = czynnikPierwsze(maksRoznychLiczba); if (set<int>(temp.begin(), temp.end()).size() > set<int>(temp2.begin(), temp2.end()).size()) { maksRoznychLiczba = liczba; } } cout << maksCzynnikowLiczba << " " << czynnikPierwsze(maksCzynnikowLiczba).size() << " "; auto temp = czynnikPierwsze(maksRoznychLiczba); cout << maksRoznychLiczba << " " << set<int>(temp.begin(), temp.end()).size() << endl; return 0; } |
Implementacja – Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | import java.io.*; import java.util.*; import java.util.stream.Collectors; public class Main { // Funkcja zwracająca czynniki pierwsze liczby public static List<Integer> czynnikPierwsze(int liczba) { List<Integer> czynniki = new ArrayList<>(); for (int i = 2; i <= liczba; i++) { while (liczba % i == 0) { czynniki.add(i); liczba /= i; } if (liczba == 1) break; } return czynniki; } public static void main(String[] args) { try { BufferedReader plik = new BufferedReader(new FileReader("liczby.txt")); List<Integer> linie = plik.lines().map(Integer::parseInt).collect(Collectors.toList()); plik.close(); // Zadanie 4.2 int maksCzynnikowLiczba = 0; int maksRoznychLiczba = 0; for (int liczba : linie) { if (czynnikPierwsze(liczba).size() > czynnikPierwsze(maksCzynnikowLiczba).size()) { maksCzynnikowLiczba = liczba; } Set<Integer> unikalneCzynniki = new HashSet<>(czynnikPierwsze(liczba)); if (unikalneCzynniki.size() > new HashSet<>(czynnikPierwsze(maksRoznychLiczba)).size()) { maksRoznychLiczba = liczba; } } System.out.println(maksCzynnikowLiczba + " " + czynnikPierwsze(maksCzynnikowLiczba).size() + " " + maksRoznychLiczba + " " + new HashSet<>(czynnikPierwsze(maksRoznychLiczba)).size()); } catch (IOException e) { e.printStackTrace(); } } } |
Potrzebne będą dwie zmienne na maksymalną liczbę. Jedna na tę która ma ich najwięcej, a druga na tę która ma najwięcej różnych czynników pierwszych.
W przypadku maksymalnej liczby czynników wystarczy sprawdzić, czy długość listy zwracanej przez czynnikiPierwsze() jest większa od listy zwracanej dla liczby obecnie zawartej w maksCzynnikowLiczba.
Sprawdzenie liczby unikalnych czynników, może wydawać się cięższe jednak wystarczy użyć funkcji set(), by przekonwertować liczbę na strukturę danych set, która przechowuje każdy element, tylko raz (jeśli dodano by tam ponownie daną liczbę, to nie jest już zapisywana). Następnie postępujemy jak w poprzednim warunku, czyli porównujemy długości.
Na koniec wyświetlamy znalezione wartości oraz liczby ich czynników. Należy pamiętać, żeby dla drugiej liczby też użyć tutaj set() inaczej zostanie zwrócona liczba wszystkich czynników, a nie tylko unikatowych.
Rozwiązanie:
Liczba o największej liczbie czynników: 99792,
Najwięcej czynników jednej liczby: 10,
Liczba o największej liczbie czynników: 62790,
Najwięcej czynników liczby: 6.
Zadanie 4.3.

Ostatni podpunkt nie jest trudny jeśli chodzi o samą logikę – wystarczy użyć instrukcji warunkowej if, żeby sprawdzić czy dana liczba jest dzielnikiem innej. Jednak nie możemy użyć tutaj podejścia brute-force, bo gdybyśmy zaczęli sprawdzać każdą liczbę z każdą, ostateczna złożoność programu byłaby olbrzymia. O ile w przypadku trójek możemy uzyskać jakiś wynik (tutaj złożoność to “tylko” O(n3)), tak dla piątek będzie to trwało bardzo długo (złożoność O(n5) dla 200 to aż 2005 operacji, czyli dokładnie 320 000 000 000 operacji), zwłaszcza w języku jakim jest python.
Zamiast za każdym razem szukać we wszystkich liczbach, lepiej dla każdej liczby stworzyć listę podzielnych przez nią liczb obecnych w pliku (jeśli mamy n liczb i sprawdzimy dla każdej n-1 liczb to mamy złożoność tylko O(n2)). Najlepszym “pojemnikiem” na tego typu dane jest słownik (w c++ mapa pełni tę samą rolę, z kolei w javie HashMap). W ramach dalszej optymalizacji możemy również posortować dane – wtedy możemy szukać kandydatów tylko w indeksach od zmiennej i, a nie od 0, co też znacznie przyśpieszy działanie programu.
Implementacja – Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | linie = sorted(linie) liczbyPodzielnePrzezDana = dict() for liczba in linie: liczbyPodzielnePrzezDana[liczba] = [] for i in range(len(linie)): for j in range(i+1, len(linie)): if linie[j] % linie[i] == 0: liczbyPodzielnePrzezDana[linie[i]].append(linie[j]) licznikTrojek = 0 licznikPiatek = 0 for liczba1 in linie: for liczba2 in liczbyPodzielnePrzezDana[liczba1]: for liczba3 in liczbyPodzielnePrzezDana[liczba2]: licznikTrojek += 1 print(liczba1,liczba2,liczba3) for liczba4 in liczbyPodzielnePrzezDana[liczba3]: for liczba5 in liczbyPodzielnePrzezDana[liczba4]: licznikPiatek += 1 print(licznikTrojek,licznikPiatek) |
Implementacja – C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | #include <iostream> #include <fstream> #include <vector> #include <algorithm> #include <set> #include <map> using namespace std; // Funkcja zwracająca czynniki pierwsze liczby vector<int> czynnikPierwsze(int liczba) { vector<int> czynniki; for (int i = 2; i <= liczba; i++) { while (liczba % i == 0) { czynniki.push_back(i); liczba /= i; } if (liczba == 1) break; // Przerwij, jeśli liczba osiągnęła 1 } return czynniki; } int main() { ifstream plik("liczby.txt"); vector<int> linie; int liczba; // Wczytanie danych z pliku while (plik >> liczba) { linie.push_back(liczba); } plik.close(); // Zadanie 4.3 sort(linie.begin(), linie.end()); map<int, vector<int>> liczbyPodzielnePrzezDana; for (int liczba : linie) { liczbyPodzielnePrzezDana[liczba] = vector<int>(); } for (size_t i = 0; i < linie.size(); i++) { for (size_t j = i + 1; j < linie.size(); j++) { if (linie[j] % linie[i] == 0) { liczbyPodzielnePrzezDana[linie[i]].push_back(linie[j]); } } } int licznikTrojek = 0; int licznikPiatek = 0; for (int liczba1 : linie) { for (int liczba2 : liczbyPodzielnePrzezDana[liczba1]) { for (int liczba3 : liczbyPodzielnePrzezDana[liczba2]) { licznikTrojek++; cout << liczba1 << " " << liczba2 << " " << liczba3 << endl; for (int liczba4 : liczbyPodzielnePrzezDana[liczba3]) { for (int liczba5 : liczbyPodzielnePrzezDana[liczba4]) { licznikPiatek++; } } } } } cout << licznikTrojek << " " << licznikPiatek << endl; return 0; } |
Implementacja – Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | import java.io.*; import java.util.*; import java.util.stream.Collectors; public class Main { // Funkcja zwracająca czynniki pierwsze liczby public static List<Integer> czynnikPierwsze(int liczba) { List<Integer> czynniki = new ArrayList<>(); for (int i = 2; i <= liczba; i++) { while (liczba % i == 0) { czynniki.add(i); liczba /= i; } if (liczba == 1) break; } return czynniki; } public static void main(String[] args) { try { BufferedReader plik = new BufferedReader(new FileReader("liczby.txt")); List<Integer> linie = plik.lines().map(Integer::parseInt).collect(Collectors.toList()); plik.close(); // Zadanie 4.3 Collections.sort(linie); Map<Integer, List<Integer>> liczbyPodzielnePrzezDana = new HashMap<>(); for (int liczba : linie) { liczbyPodzielnePrzezDana.put(liczba, new ArrayList<>()); } for (int i = 0; i < linie.size(); i++) { for (int j = i + 1; j < linie.size(); j++) { if (linie.get(j) % linie.get(i) == 0) { liczbyPodzielnePrzezDana.get(linie.get(i)).add(linie.get(j)); } } } int licznikTrojek = 0; int licznikPiatek = 0; for (int liczba1 : linie) { for (int liczba2 : liczbyPodzielnePrzezDana.get(liczba1)) { for (int liczba3 : liczbyPodzielnePrzezDana.get(liczba2)) { licznikTrojek++; System.out.println(liczba1 + " " + liczba2 + " " + liczba3); for (int liczba4 : liczbyPodzielnePrzezDana.get(liczba3)) { for (int liczba5 : liczbyPodzielnePrzezDana.get(liczba4)) { licznikPiatek++; } } } } } System.out.println(licznikTrojek + " " + licznikPiatek); } catch (IOException e) { e.printStackTrace(); } } } |
Dla każdej liczby w słowniku dodajemy listę liczb, które dana wartość dzieli – prowadzi to do powstawania dość sporej redundancji danych (powielania tych samych informacji w różnych miejscach), przez co zajmuje dość dużo pamięci, ale nie ma to znaczenia na maturze.
Teraz wszystko już gotowe po prostu tworzymy pięć pętli zagnieżdżonych i przeszukujemy kolejne listy uzyskane ze słowników. W 3 pętli inkrementujemy licznikTrojek, a w 5 pętli licznikPiątek. Na koniec wyświetlamy zmienną licznik. Zadanie jest gotowe, pamiętaj żeby umieścić odpowiedzi w pliku wyniki4.txt.
Rozwiązanie:
232 13688 27376
392 20384 61152
409 9816 58896
497 22365 89460
797 7173 64557
871 15678 62712
955 8595 42975
971 6797 13594
971 6797 27188
971 6797 81564
971 13594 27188
971 13594 81564
971 27188 81564
1403 2806 8418
1403 2806 42090
1403 2806 84180
1403 8418 42090
1403 8418 84180
1403 42090 84180
2806 8418 42090
2806 8418 84180
2806 42090 84180
6797 13594 27188
6797 13594 81564
6797 27188 81564
8418 42090 84180
13594 27188 81564
dobrych trójek: 27 dobrych piątek: 2
Pełny kod 4.1 – 4.3 – implementacja w python, C++ i java
Implementacja – Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | def czynnikPierwsze(liczba): czynniki = [] for i in range(2,liczba+1): while liczba % i == 0: czynniki.append(i) liczba //= i if liczba == 1: break return czynniki with open("liczby.txt") as plik: linie = plik.readlines() for i in range(len(linie)): linie[i] = int(linie[i].rstrip()) #zadanie 4.1 licznik = 0 pierwsza = 0 for liczba in linie: liczba = str(liczba) if liczba[0] == liczba[-1]: licznik += 1 if pierwsza == 0: pierwsza = liczba print(licznik,pierwsza) #zadanie 4.2 maksCzynnikowLiczba = 0 maksRoznychLiczba = 0 for liczba in linie: if len(czynnikPierwsze(liczba)) > len(czynnikPierwsze(maksCzynnikowLiczba)): maksCzynnikowLiczba = liczba if len(set(czynnikPierwsze(liczba))) > len(set(czynnikPierwsze(maksRoznychLiczba))): maksRoznychLiczba = liczba print(maksCzynnikowLiczba,len(czynnikPierwsze(maksCzynnikowLiczba)),maksRoznychLiczba,len(set(czynnikPierwsze(maksRoznychLiczba)))) #zadanie 4.3 linie = sorted(linie) liczbyPodzielnePrzezDana = dict() for liczba in linie: liczbyPodzielnePrzezDana[liczba] = [] for i in range(len(linie)): for j in range(i+1, len(linie)): if linie[j] % linie[i] == 0: liczbyPodzielnePrzezDana[linie[i]].append(linie[j]) licznikTrojek = 0 licznikPiatek = 0 for liczba1 in linie: for liczba2 in liczbyPodzielnePrzezDana[liczba1]: for liczba3 in liczbyPodzielnePrzezDana[liczba2]: licznikTrojek += 1 print(liczba1,liczba2,liczba3) for liczba4 in liczbyPodzielnePrzezDana[liczba3]: for liczba5 in liczbyPodzielnePrzezDana[liczba4]: licznikPiatek += 1 print(licznikTrojek,licznikPiatek) |
Implementacja – C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | #include <iostream> #include <fstream> #include <vector> #include <algorithm> #include <set> #include <map> using namespace std; // Funkcja zwracająca czynniki pierwsze liczby vector<int> czynnikPierwsze(int liczba) { vector<int> czynniki; for (int i = 2; i <= liczba; i++) { while (liczba % i == 0) { czynniki.push_back(i); liczba /= i; } if (liczba == 1) break; // Przerwij, jeśli liczba osiągnęła 1 } return czynniki; } int main() { ifstream plik("liczby.txt"); vector<int> linie; int liczba; // Wczytanie danych z pliku while (plik >> liczba) { linie.push_back(liczba); } plik.close(); // Zadanie 4.1 int licznik = 0; int pierwsza = 0; for (int liczba : linie) { string liczbaStr = to_string(liczba); if (liczbaStr[0] == liczbaStr.back()) { licznik++; if (pierwsza == 0) { pierwsza = liczba; } } } cout << licznik << " " << pierwsza << endl; // Zadanie 4.2 int maksCzynnikowLiczba = 0; int maksRoznychLiczba = 0; for (int liczba : linie) { if (czynnikPierwsze(liczba).size() > czynnikPierwsze(maksCzynnikowLiczba).size()) { maksCzynnikowLiczba = liczba; } auto temp = czynnikPierwsze(liczba); auto temp2 = czynnikPierwsze(maksRoznychLiczba); if (set<int>(temp.begin(), temp.end()).size() > set<int>(temp2.begin(), temp2.end()).size()) { maksRoznychLiczba = liczba; } } cout << maksCzynnikowLiczba << " " << czynnikPierwsze(maksCzynnikowLiczba).size() << " "; auto temp = czynnikPierwsze(maksRoznychLiczba); cout << maksRoznychLiczba << " " << set<int>(temp.begin(), temp.end()).size() << endl; // Zadanie 4.3 sort(linie.begin(), linie.end()); map<int, vector<int>> liczbyPodzielnePrzezDana; for (int liczba : linie) { liczbyPodzielnePrzezDana[liczba] = vector<int>(); } for (size_t i = 0; i < linie.size(); i++) { for (size_t j = i + 1; j < linie.size(); j++) { if (linie[j] % linie[i] == 0) { liczbyPodzielnePrzezDana[linie[i]].push_back(linie[j]); } } } int licznikTrojek = 0; int licznikPiatek = 0; for (int liczba1 : linie) { for (int liczba2 : liczbyPodzielnePrzezDana[liczba1]) { for (int liczba3 : liczbyPodzielnePrzezDana[liczba2]) { licznikTrojek++; cout << liczba1 << " " << liczba2 << " " << liczba3 << endl; for (int liczba4 : liczbyPodzielnePrzezDana[liczba3]) { for (int liczba5 : liczbyPodzielnePrzezDana[liczba4]) { licznikPiatek++; } } } } } cout << licznikTrojek << " " << licznikPiatek << endl; return 0; } |
Implementacja – Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | import java.io.*; import java.util.*; import java.util.stream.Collectors; public class Main { // Funkcja zwracająca czynniki pierwsze liczby public static List<Integer> czynnikPierwsze(int liczba) { List<Integer> czynniki = new ArrayList<>(); for (int i = 2; i <= liczba; i++) { while (liczba % i == 0) { czynniki.add(i); liczba /= i; } if (liczba == 1) break; } return czynniki; } public static void main(String[] args) { try { BufferedReader plik = new BufferedReader(new FileReader("liczby.txt")); List<Integer> linie = plik.lines().map(Integer::parseInt).collect(Collectors.toList()); plik.close(); // Zadanie 4.1 int licznik = 0; int pierwsza = 0; for (int liczba : linie) { String liczbaStr = Integer.toString(liczba); if (liczbaStr.charAt(0) == liczbaStr.charAt(liczbaStr.length() - 1)) { licznik++; if (pierwsza == 0) { pierwsza = liczba; } } } System.out.println(licznik + " " + pierwsza); // Zadanie 4.2 int maksCzynnikowLiczba = 0; int maksRoznychLiczba = 0; for (int liczba : linie) { if (czynnikPierwsze(liczba).size() > czynnikPierwsze(maksCzynnikowLiczba).size()) { maksCzynnikowLiczba = liczba; } Set<Integer> unikalneCzynniki = new HashSet<>(czynnikPierwsze(liczba)); if (unikalneCzynniki.size() > new HashSet<>(czynnikPierwsze(maksRoznychLiczba)).size()) { maksRoznychLiczba = liczba; } } System.out.println(maksCzynnikowLiczba + " " + czynnikPierwsze(maksCzynnikowLiczba).size() + " " + maksRoznychLiczba + " " + new HashSet<>(czynnikPierwsze(maksRoznychLiczba)).size()); // Zadanie 4.3 Collections.sort(linie); Map<Integer, List<Integer>> liczbyPodzielnePrzezDana = new HashMap<>(); for (int liczba : linie) { liczbyPodzielnePrzezDana.put(liczba, new ArrayList<>()); } for (int i = 0; i < linie.size(); i++) { for (int j = i + 1; j < linie.size(); j++) { if (linie.get(j) % linie.get(i) == 0) { liczbyPodzielnePrzezDana.get(linie.get(i)).add(linie.get(j)); } } } int licznikTrojek = 0; int licznikPiatek = 0; for (int liczba1 : linie) { for (int liczba2 : liczbyPodzielnePrzezDana.get(liczba1)) { for (int liczba3 : liczbyPodzielnePrzezDana.get(liczba2)) { licznikTrojek++; System.out.println(liczba1 + " " + liczba2 + " " + liczba3); for (int liczba4 : liczbyPodzielnePrzezDana.get(liczba3)) { for (int liczba5 : liczbyPodzielnePrzezDana.get(liczba4)) { licznikPiatek++; } } } } } System.out.println(licznikTrojek + " " + licznikPiatek); } catch (IOException e) { e.printStackTrace(); } } } |
Zadanie 5 – Sok

Na początek do osobnego arkusza importujemy dane. Po zaimportowaniu najlepiej już w nim nic nie zmieniać tylko dla każdego podpunktu utworzyć nowy arkusz. Wtedy mamy pewność, że dane nie zostaną w żaden sposób przez nas zmienione co doprowadziłoby do złych odpowiedzi.
Zadanie 5.1.

Po zaznaczeniu zakresu danych, który chcesz poddać analizie, kliknij Wstawianie, a następnie Tabela przestawna.

W tym podpunkcie wystarczy utworzyć tabelę przestawną z polem magazyn w sekcji wiersze oraz dowolnym innym polem w sekcji wartości. Nie warto do tego wybierać kolumny wielkosc_zamowienia, ponieważ to domyślnie zsumuje wartości. Gdyby jednak ktoś się na to zdecydował, należy zmienić typ podsumowania wartości z Suma na Licznik. Wybierając np. datę zamiast wielkosc_zamowienia nie byłoby tego problemu, ponieważ Licznik zostałby wybrany domyślnie.

Rozwiązanie:
Etykiety wierszy | Sumy |
Gniezno | 152 |
Malbork | 183 |
Ogrodzieniec | 222 |
Przemysl | 198 |
Zadanie 5.2.

Drugi podpunkt to typowe zadanie na znajdowanie ciągu rosnącego. Jednak najpierw trzeba odseparować magazyn Ogrodzieniec od reszty. W tym celu znów tworzymy tabele przestawną. Do sekcji wiersze wstawiamy data, a jako filtr dajemy magazyn i wybieramy ogrodzieniec. Teraz obok tabeli dodajmy zwykłą kolumnę w której poszczególnych wierszach sprawdzamy, czy data różni się o 1 – jeśli tak, zwiększamy licznik o jeden, a jeśli nie to wstawiamy jedynkę. W pierwszym wierszu kolumny należy wpisać jedynkę manualnie, ponieważ wyskoczy tam błąd związany z brakiem liczby w wierszu tytułowym.

Następnie używając funkcji MAX na kolumnie ciagle znajdujemy największą wartość. Teraz za pomocą ctrl+F wystarczy tę wartość znaleźć i przepisać datę początkową, końcową oraz największą wartość do pliku.
Rozwiązanie:
liczba dni – 8 data pierwszego i ostatniego dnia – 07.10.2021 i 14.10.2021
Zadanie 5.3.

Tutaj znowu posłużymy się tabelą przestawną, wystarczy dodać magazyn do sekcji wiersze i wartosc_zamowienia do sekcji wartosci. Następnie zaznaczamy nowo utworzoną tabelę i tworzymy wykres. Wystarczy przejść do sekcji Wstawianie we wstążce i kliknąć Polecane wykresy. Wybieramy opcję wykres kołowy i wstawiamy go. Jednak to nie wszystko, trzeba jeszcze przerobić go na wykres procentowy, dlatego klikamy na wykres prawym przyciskiem myszy i wybieramy opcję Dodaj etykiety danych. Gdy już się pojawią. klikamy na nie prawym przyciskiem myszy i wybieramy Formatuj etykiety danych. Teraz w panelu bocznym przechodzimy do sekcji opcje etykiety, gdzie odznaczamy Wartość i zaznaczamy Wartość procentowa. Na koniec zmieniamy tytuł na taki, który dobrze określa co na nim jest.

Teraz wystarczy zapisać wykres poprzez np. skopiowanie go do painta i zapisanie tam jako obraz, trzeba też skopiować zestawienie do pliku txt.
Zadanie 5.4 – 5.5.

Zadania 5.4 oraz 5.5 to tak zwane zadania symulacyjne. Na podstawie dostępnych danych trzeba przeprowadzić symulację, bez wygenerowania nowych danych nie da się uzyskać odpowiedzi, a błąd na początku symulacji doprowadzi do złych wyników. Przed przejściem do implementacji warto przeczytać wszystkie kroki symulacji oraz podpunkty, które jej dotyczą. Często okazuje się, że coś wymienione wyżej w poleceniu, zależy od czegoś na dole polecenia, w tym przypadku jest to informacja o braku soku i filii.
Na początku tworzymy nową kolumnę stan magazynu na początku i tutaj jak sama nazwa wskazuje, będzie przechowywany stan magazynu na początku produkcji. Na razie uzupełniamy pierwszy wiersz i jak czytamy w poleceniu wstawiamy tutaj 30 000.
Następnie dodajemy kolumnę ile wyprodukowano tutaj musimy się już trochę wysilić i stworzyć jakąś funkcję. Jedyne od czego zależy produkcja to dzień tygodnia, używamy więc funkcji ORAZ() i DZIEŃ.TYG() żeby to sprawdzić, to wszystko wystarczy teraz dodać do funkcji jeżeli. Finalnie wygląda to tak: =JEŻELI(ORAZ(DZIEŃ.TYG(B2;2)<>6;DZIEŃ.TYG(B2;2)<>7);12000;5000) gdzie B to kolumna z datą.
Teraz czas na uzupełnienie magazynów wyprodukowanymi produktami, tworzymy więc kolumnę stan po produkcji w której sumujemy stan magazynu przed produkcją i wartość z kolumny ile wyprodukowano.
Teraz wypadałoby przejść do zamówień, jednak trzeba najpierw sprawdzić, czy czasem nie musimy przekazać danego zamówienia do filii. Jak czytamy w opisie symulacji, dzieje się tak kiedy zamówienie jest większe od stanu magazynu, wystarczy użyć JEŻELI() z tym prostym warunkiem i zwracać 1 lub 0.
Ta funkcja wygląda tak: =JEŻELI(G2<D2;1;0), gdzie G2 to stan po produkcji, a D2 to wielkość zamówienia.
Na koniec zostaje obsłużyć zamówienie. Dodajemy kolumnę stan po zamówieniu w której wystarczy sprawdzić, czy w kolumnie czy przekazano fili jest 1, jeśli tak to po prostu przenosimy wartość z kolumny stan magazynu po produkcji, a w przeciwnym razie odjąć od niej wartość zamówienia. Wystarczy użyć standardowego jeżeli =JEŻELI(H2=1;G2;G2-D2).

Jednak to nie wszystko, ponieważ czeka na nas jeszcze parę pułapek. W drugim wierszu musimy trochę zmodyfikować nasze funkcje. W kolumnie stan magazynu przed produkcja, będziemy wstawiać wartość z kolumny stan po zamówieniu. Wydawałoby się, że nie musimy nic zmieniać w funkcji zwracającej liczbę wyprodukowanych litrów soku, jednak jest to błąd. Przecież w pliku jedna data może pojawiać się kilkukrotnie! Gdybyśmy nie uwzględnili tego w naszej symulacji, w jeden dzień moglibyśmy mieć znacznie zawyżoną produkcję. Trzeba więc naszą funkcję owinąć w dodatkowy warunek, który sprawdzi, czy dzień różni się od tego wiersz wyżej i wstawi 0 jeśli dojdzie do takiej sytuacji. Teraz nasza funkcja wygląda tak: =JEŻELI(B3<>B2;JEŻELI(ORAZ(DZIEŃ.TYG(B3;2)<>6;DZIEŃ.TYG(B3;2)<>7);12000;5000);0)
Uwaga: Nie należy oczywiście zmieniać funkcji w pierwszym wierszu.
W pozostałych kolumnach nic nie zmieniamy, możemy po prostu przeciągnąć funkcje z pierwszego wiersza w dół.
Rozwiązanie:

Zadanie 5.4

Dzięki uwadze zostawionej nam przez CKE, możemy łatwo sprawdzić poprawność naszej symulacji.
Żeby rozwiązać ten podpunkt wystarczy użyć tabeli przestawnej z filtrem na czy przekazano filii. Teraz do wartości dajemy kolumny data oraz wielkość zamówienia.

Rozwiązanie:
285230
Zadanie 5.5.

Do tego zadania warto skopiować arkusz z podpunktu z symulacją do nowego arkusza, bo bardzo łatwo coś popsuć. Będziemy używać zakładki Deweloper. W zakładce deweloper klikamy wstaw i wybieramy dość niefortunnie nazwane pole pokrętła, następnie umieszczamy je z boku tabeli.

Po wstawieniu przycisku klikamy na niego prawym przyciskiem myszy i klikamy Formatuj formant… następnie wybieramy dowolną pustą komórkę w sekcji pole komórki.

Jak widać, jest to stosunkowo proste rozwiązanie.

Teraz zawartość komórki ustawiamy na domyślną wartość produkcji w dzień roboczy, czyli 12000. Następnie w funkcji odpowiedzialnej za zwracanie liczby wyprodukowanych butelek zamiast 12000 dajemy zablokowaną wybraną przez nas wcześniej komórkę. Ostatecznie funkcja wygląda tak: =JEŻELI(B3<>B2;JEŻELI(ORAZ(DZIEŃ.TYG(B3;2)<>6;DZIEŃ.TYG(B3;2)<>7);$K$9;5000);0)
Teraz używając funkcji LICZ.JEŻELI() w innej komórce zliczamy jedynki w kolumnie czy przekazano filii (jeśli u ciebie też funkcja sprawdzająca zwraca 0 i 1, możesz użyć funkcji SUMA()). Możemy zacząć klikać przycisk ze strzałką w górę, nasza wartość produkcji w dzień roboczy zacznie się zwiększać, a liczba przekazań do filii zmniejszać. Warto zmienić domyślny krok na np. 100 i potem stopniowo go zmniejszać np. od 10 aż w końcu do jednego, by znaleźć pierwszą wartość dla której LICZ.JEŻELI zwraca 0.
Zadanie 6 – System kontroli dostępu

Na początek należy zaimportować wszystkie pliki txt do odpowiednich tabeli. Nie powinno to być zbyt problematyczne, należy jednak zwracać szczególną uwagę na odpowiedni format daty.

Przed podejściem do rozwiązywania zadań trzeba też stworzyć odpowiednie relacje. Należy połączyć Ewidencja.idUcznia z Uczen.IdUcznia oraz Uczen.IdKlasy z Klasa.IdKlasy.
Zadanie 6.1.

W tym podpunkcie wykorzystamy wszystkie 3 tabele. Najpierw dodamy tabelę Ewidencja i dodamy z niej dowolne pole np. IdEwidencji. Z tabeli uczen musimy wyjąć Imie i dać filtr Like “*a”, to spowoduje, że wyświetlone zostaną tylko imiona kończące się na a. Musimy też dodać pole Klasa.ProfilKlasy i dać filtr “biologiczno-chemiczny”, teraz wystarczy przejść do widoku arkusza danych i przeczytać ile wierszy jest wyświetlanych. To właśnie jest odpowiedź do tego podpunktu. (jeśli zamiast 1 z [liczba wierszy] wyświetla się po prostu 1 z, musisz zjechać na sam dół arkusza).

Rozwiązanie:
165
Zadanie 6.2.

W tym podpunkcie musimy posłużyć się tabelami pomocniczymi, najpierw w każdym dniu policzymy liczbę wejść, czyli liczbę obecności. Możemy to założyć, dzięki informacji podanej w poleceniu. Pierwsza tabela pomocnicza opiera się tylko na tabeli Ewidencja. W celu uzyskania daty klikamy prawym przyciskiem myszy na pustą komórkę w wierszu pole i wybieramy opcję konstruuj.

Teraz używając funkcji DateValue na Ewidencja.wejscie możemy wyciągnąć datę.

Teraz dodajemy inne dowolne pole z tabeli i po włączeniu opcji sum w zakładce Projekt kwerendy na datę, włączamy sumę Grupuj według, na drugie pole Policz.

Teraz stworzymy drugą kwerendę pomocniczą, która będzie zawierać liczbę spóźnień. Kopiujemy poprzednią kwerendę i dodajmy do niej nową kolumnę klikając prawym przyciskiem myszy na komórkę w wierszu Pole, po czym wybieramy konstruuj. Teraz używamy funkcji TimeValue() na polu Ewidencja.Wejscie. Następnie wystarczy ustawić sumę Gdzie i dodać filtr >#08:00:00#. # muszą być podane przy datach i godzinach. Teraz wystarczy stworzyć trzecią kwerendę, w której dla każdego dnia odejmiemy liczbę spóźnień od liczby obecności.
Wyjmujemy pole odpowiadające dacie z dowolnej kwerendy, a następnie konstruujemy nowe pole, gdzie odejmujemy od pola odpowiadającego liczbie obecności pole odpowiadające liczbie spóźnień. Teraz nasze zestawienie jest już gotowe

Rozwiązanie:
Wyr1 | Wyr2 |
---|---|
04.04.2022 | 233 |
05.04.2022 | 303 |
06.04.2022 | 134 |
07.04.2022 | 280 |
08.04.2022 | 127 |
Zadanie 6.3.

Tworzymy nową kwerendę i dodajemy tabele Ewidencja oraz Uczen. Z tabeli Uczen wyjmujemy IdUcznia, Imie, Nazwisko (IdUcznia dodajemy bo uczniowie mogą nazywać się tak samo). Teraz konstruujemy nowe wyrażenie i używając funkcji suma sumujemy wszystkie różnice wyjścia i wejścia.

Teraz wystarczy ustawić sortowanie malejące na nowo dodaną kolumnę, wyświetlić wynik i skopiować pierwsze 3 wyniki.
Rozwiązanie:
IdUcznia | Imie | Nazwisko |
---|---|---|
314 | Sebastian | Rabaj |
172 | Monika | Kado |
299 | Alicja | Kronecka |
Zadanie 6.4.

Tworzymy nową kwerendę i dodajemy tabele Ewidencja oraz Uczen. Do naszej kwerendy dodajemy IdUczen i konstruujemy nową kolumnę używając funkcji DateValue na polu Ewidencja.Wejscie. Ta kwerenda będzie naszą kwerendą pomocniczą, gdzie znajdują się wszyscy uczniowie, którzy byli obecni 06.04.2022.
Teraz tworzymy kolejna kwerendę, dodając tabelę Uczen oraz kwerendę pomocniczą. Tworzymy między nimi relację na polach IdUcznia. Jednak zmieniamy typ relacji na taki, który uwzględnia wszystkie rekordy z tabeli Uczen.

Teraz dodajemy pola Uczen.IdUcznia, Uczen.Imie, Uczen.Nazwisko, [nazwaKwerendyPomocniczej].IdUcznia i na tę kwerendę dodajmy filtr Is Null, co spowoduje wyświetlenie uczniów, których id nie pojawiło się na liście obecności z dnia 06.04.2022.

Rozwiązanie:
Imie | Nazwisko |
Mateusz | Kordas |
Krzysztof | Michalak |
Oliwier | Ziolko |
Wpisy, które mogą Cię zainteresować: