Prezentowane materiały są przeznaczone dla uczniów szkół ponadgimnazjalnych. Autor artykułu: mgr Jerzy Wałaszek, wersja1.0 |
©2013 mgr
Jerzy Wałaszek
|
Pierwsza kaczka zostanie pożarta jako piąta z kolei, drugą kaczkę aligator zje jako czwartą z kolei, itd. Ciąg 5 4 6 1 3 8 7 2 kolejności zjadania kaczek całkowicie określa jadłospis aligatora. Napisz program, który określi ten ciąg dla danych n i m.
8 4
10 3
0 0
5 4 6 1 3 8 7 2
6 4 1 10 8 2 5 7 3 9
Teraz ustawiamy licznik zjedzonych kaczek lk = 0 oraz numer kaczki do zjedzenia nk = n - 1 (jest to ostatnia pozycja w kręgu – chodzi o to, aby odliczanie kaczek rozpoczęło się od następnej, czyli pierwszej w kręgu).
W pętli dopóki lk < n wykonujemy cyklicznie operacje:
Dla n = 8 i m = 4:
lk = 0
nk = 7
komórka | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
indeks | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
nk |
lk = 1
nk = 3
komórka | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 2 |
indeks | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
nk |
lk = 2
nk = 7
komórka | 0 | 0 | 0 | 1 | 3 | 0 | 0 | 2 |
indeks | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
nk |
lk = 3
nk = 4
komórka | 0 | 4 | 0 | 1 | 3 | 0 | 0 | 2 |
indeks | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
nk |
lk = 4
nk = 1
komórka | 5 | 4 | 0 | 1 | 3 | 0 | 0 | 2 |
indeks | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
nk |
lk = 5
nk = 0
komórka | 5 | 4 | 6 | 1 | 3 | 0 | 0 | 2 |
indeks | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
nk |
lk = 6
nk = 2
komórka | 5 | 4 | 6 | 1 | 3 | 0 | 7 | 2 |
indeks | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
nk |
lk = 7
nk = 2
komórka | 5 | 4 | 6 | 1 | 3 | 8 | 7 | 2 |
indeks | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
nk |
lk = 8 - koniec, tablica jest wypełniona.
// Koło Informatyczne I LO w Tarnowie // (C)2013 mgr Jerzy Wałaszek // ACM - Jadłospis Aligatora // PRG_40 //----------------------------------- #include <iostream> #include <iomanip> using namespace std; int main() { int * K,n,m,lk,nk; while(true) { cin >> n >> m; // Odczytujemy liczbę kaczek i krok if(!n || !m) break; // Tworzymy tablicę dynamiczną K = new int [n]; // Tablicę zerujemy for(int i = 0; i < n; i++) K[i] = 0; // Inicjujemy dane lk = 0; nk = n - 1; // W pętli wyznaczamy kolejno jedzone kaczki while(lk < n) { for(int i = 0; i < m; i++) do { nk++; if(nk == n) nk = 0; } while(K[nk]); K[nk] = ++lk; } // Wyświetlamy zawartość tablicy for(int i = 0; i < n; i++) cout << setw(3) << K[i]; cout << endl; // Usuwamy tablicę dynamiczną delete [] K; } return 0; } |
Podany powyżej algorytm nie jest specjalnie efektywny. Program musi wciąż wielokrotnie przechodzić przez wykorzystane elementy w tablicy (czyli pomijać kaczki, które wcześniej zjadł aligator). Aby poprawić efektywność działania programu, musimy zmodyfikować strukturę danych, która przechowuje numery kolejno zjedzonych kaczek.
Elementy łączymy w listę wpisując w ich pola next adresy elementów następnych. Lista staje się cykliczna, gdy w polu next ostatniego elementu wpiszemy adres elementu pierwszego.
Lista posiada niewątpliwą zaletę – można z niej prosto usuwać elementy. Element usunięty nie jest już częścią listy i nie będzie odwiedzany. Usunięcie elementu polega na wpisaniu do pola next elementu poprzedzającego adresu z pola next elementu usuwanego. W ten sposób poprzedni element nie będzie już adresował usuniętego elementu, lecz jego element następny. Poniższy przykład pokazuje usuwanie elementu e2.
Po tej operacji przejście przez listę omija element e2.
Zasada działania zmodyfikowanego programu jest następująca:
// Koło Informatyczne I LO w Tarnowie // (C)2013 mgr Jerzy Wałaszek // ACM - Jadłospis Aligatora II // PRG_41 //----------------------------------- #include <iostream> #include <iomanip> using namespace std; // Definicja elementu listy //------------------------- struct list_element { list_element * next; int data; }; int main() { list_element * E; // dynamiczna tablica elementów listy cyklicznej list_element * p; // wskaźnik elementów listy int n,m,i,lk; // W pętli wyznaczamy kolejne rozwiązania while(true) { cin >> n >> m; // odczytujemy liczbę kaczek n oraz odstęp m if(!n || !m) break; // Tworzymy tablicę dynamiczną E = new list_element [n]; // Tworzymy listę cykliczną for(i = 0; i <= n - 2; i++) E[i].next = &E[i+1]; E[n-1].next = &E[0]; // Rozpoczynamy ucztę aligatora p = &E[n-1]; // wskaźnik elementu poprzedzającego element usuwany lk = 0; // licznik zjedzonych kaczek while(lk < n) { // Ustawiamy p na element poprzedzający "kaczkę do zjedzenia" for(i = 0; i < m - 1; i++) p = p->next; // Do "zjadanej kaczki" zapisujemy jej numer p->next->data = ++lk; // "Zjedzoną kaczkę" usuwamy z listy p->next = p->next->next; } // Wypisujemy numery zjedzonych kaczek for(i = 0; i < n; i++) cout << setw(3) << E[i].data; cout << endl; // Tablicę-listę usuwamy z pamięci delete [] E; } return 0; } |
I Liceum Ogólnokształcące |
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe