/* Trochę kodu w C/C++ poziom abstrakcji jest dosyć wysoki.. chodzi o samą ideę rozwiązania */ // input: n // input: tab [a1][b1] // input: tab [a2][b2] // input: tab [an][bn] ////////////////////////////////////////////////////////////////////// // definicja nowego typu danych "pole" zawierającego dwa rekordy typu int ////////////////////////////////////////////////////////////////////// typedef struct _pole { int numer_pola; int liczba_pionkow; } pole; // lista dwukierunkowa w C++ jest zaimplementowana już w bibliotece STL // (jeśli mnie pamięć nie myli).. a jeśli nie można z niej korzystać, to trzeba // zrobić własną implementacje.. gdzieś mogę wygrzebać prawdopodobnie // implementację listy dwukierunkowej w C, którą kiedyś robiłem i działała // potrzebna będzie lista dwukierunkowa, której elementy będą typu pole // do listy dodajemy elementy, które zostają wczytane // z pliku z danymi wejściowymi ////////////////////////////////////////////////////////////////////// // Funkcja wykonuje przekształcenia zgodnie z ruchem w lewo // zdefiniowanym w treści zadania ////////////////////////////////////////////////////////////////////// void ruch_lewo(*wsk_aktualny_element) { if (wsk_aktualny_element.poprzedniElement == NULL) { // jeśli nie istnieje poprzednik aktualnie badanego elementu, // to trzeba go stworzyć pole *nowy_element = new pole; // nowemu elementowi przypisujemy numer pola mniejszy o jeden // względem badanego elementu nowy_element.numer_pola = wsk_aktualny_element.numer_pola - 1; nowy_element.liczba_pionkow = 1; // ustawiamy elementy w odpowiedniej relacji wzlgędem siebie wsk_aktualny_element.poprzedniElement = &nowy_element; nowy_element.nastepnyElement = &wsk_aktualny_element; // jeśli użyta będzie lista z biblioteki to nie trzeba będzie // tego wszystkiego robić ręcznie // -- // w tym momencie wiemy też, że nie istnieje element poprzedzający // do dopiero co stworzonego nowego elementu, więc możemy // od razu dodać jeszcze jeden, zgodnie z ruchem w lewo wsk_aktualny_element = &nowy_element; pole *nowy_element = new pole; nowy_element.numer_pola = wsk_aktualny_element.numer_pola - 1; nowy_element.liczba_pionkow = 1; wsk_aktualny_element.poprzedniElement = &nowy_element; nowy_element.nastepnyElement = &wsk_aktualny_element; } else { // jeśli element poprzedzający badany element istnieje... // ... to sprawdzamy czy ma swojego poprzednika if (wsk_aktualny_element.poprzedniElement.poprzedniElement != NULL) { // jeśli posiada poprzednika // to dodajemy do jego liczby pionków wartość 1 poprzedniElement = &wsk_aktualny_element.poprzedniElement.poprzedniElement; poprzedniElement.liczba_pionkow += 1; } else { // jeśli nie posiada poprzednika // to trzeba go stworzyć... pole *nowy_element = new pole; nowy_element.numer_pola = wsk_aktualny_element.poprzedniElement.numer_pola - 1; nowy_element.liczba_pionkow = 1; nowy_element.nastepnyElement = &wsk_aktualny_element.poprzedniElement; wsk_aktualny_element.poprzedniElement.poprzedniElement = &nowy_element; } } // zmniejszamy wartość liczby pionków aktualnie badanego elementu // o jeden wsk_aktualny_element.liczba_pionkow -= 1; } ////////////////////////////////////////////////////////////////////// // Funkcja wykonuje przekształcenia zgodnie z ruchem w prawo // zdefiniowanym w treści zadania ////////////////////////////////////////////////////////////////////// void ruch_prawo(*wsk_aktualny_element) { // jeżeli nie istnieje poprzednik dla aktualnie badanego elementu // to trzeba go stworzyć if (wsk_aktualny_element.poprzedniElement == NULL) { pole *nowy_element = new pole; nowy_element.numer_pola = wsk_aktualny_element.numer_pola - 1; nowy_element.liczba_pionkow = -1 ; wsk_aktualny_element.poprzedniElement = &nowy_element; nowy_element.nastepnyElement = &wsk_aktualny_element; } else { // jeżeli istnieje poprzednik... wsk_aktualny_element.poprzedniElement.liczba_pionkow -= 1; } // jeżeli nie istnieje element następujący po aktualnie badanym elemencie // to trzeba go stworzyć if (wsk_aktualny_element.nastepnyElement == NULL) { pole *nowy_element = new pole; nowy_element.numer_pola = wsk_aktualny_element.numer_pola + 1; nowy_element.liczba_pionkow = 1; wsk_aktualny_element.nastepnyElement = &nowy_element; nowy_element.poprzedniElement = &wsk_aktualny_element; } else { // jeśli istnieje następujący element... wsk_aktualny_element.nastepnyElement.liczba_pionkow += 1; } // zmniejszamy wartość liczby pionków aktualnie badanego elementu // o jeden wsk_aktualny_element.liczba_pionkow -= 1; } ////////////////////////////////////////////////////////////////////// // Funkcja wypisująca wynik końcowy po przekształceniach ////////////////////////////////////////////////////////////////////// void wypisz_wynik(lista) { // funkcja wypisze całą zawartość listy w postaci // a1 b1 // a2 b2 // .. .. // aN bN pole *wsk_aktualny_element; // wsk_aktualny element podczas wywołania // funkcji musi wskazywać na pierwszy // element listy for(wsk_aktualny_element = &lista; \ // wsk_aktualny_element podczas // inicjalizacji pętli powinien wskazywać // na pierwszy element listy wsk_aktualny_element.nastepnyElement != NULL; \// pętla zatrzyma się w momencie, // w którym element, który jest wskazywany przez // wsk_aktualny_element.nextElement będzie pusty // (nie będzie kolejnego elementu w liście) wsk_aktualny_element = wsk_aktualny_element.nastepnyElement) { printf("%d %d", wsk_aktualny_element.numer_pola, \ wsk_aktualny_element.liczba_pionkow); } } ////////////////////////////////////////////////////////////////////// // Inicjalizacja listy danymi wejściowymi ////////////////////////////////////////////////////////////////////// FILE *f; // wskaźnik na deskryptor pliku f.open('input.txt', 'r'); // otwieramy plik do odczytu pole *lista = inicjalizuj_liste(); // tutaj trzeba użyć własnej implementacji // lub gotowców z bibliotek for (i=0; i max_element.liczba_pionkow) { max_element = wsk_aktualny_element; } } // jeśli znalezionym maximum jest liczba pionków = 1 // oznacza to, że skończyliśmy algorytm i możemy wyjśc z pętli while if (max_element.liczba_pionkow == 1) { _koniec = true; break; // wychodzimy z pętli } // w tym momencie mamy wyznaczone nasze maximum w tej iteracji // (tylko jeśli nie nastąpił _koniec) if ( _koniec == false) { // sprawdzamy, czy poprzedzający element istnieje.. if (max_element.poprzedniElement != NULL) { // jeśli istnieje, to sprawdzamy, czy jego liczba pionków // jest mniejsza od zera if (max_element.poprzedniElement.liczba_pionkow < 0) { // jesli tak, to robimy ruch w lewo ruch_lewo(&max_element); } else { // jeśli liczba pionków poprzedzającego elementu jest większa, // lub równa zero, to lecimy z ruchem w prawo } } else { // jeśli poprzedzający element nie istnieje, to robimy ruch w prawo ruch_prawo(&max_element); } } } // w tym miejscu możemy już wyświetlić wynik końcowy wypisz_wynik(&lista);