Advertisement
s4ros

zadanie studenciaka

May 28th, 2014
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.80 KB | None | 0 0
  1. /*
  2.    Trochę kodu w C/C++
  3.    poziom abstrakcji jest dosyć wysoki.. chodzi o samą ideę rozwiązania
  4. */
  5. // input: n
  6. // input: tab [a1][b1]
  7. // input: tab [a2][b2]
  8. // input: tab [an][bn]
  9.  
  10. //////////////////////////////////////////////////////////////////////
  11. // definicja nowego typu danych "pole" zawierającego dwa rekordy typu int
  12. //////////////////////////////////////////////////////////////////////
  13. typedef struct _pole {
  14.    int numer_pola;
  15.    int liczba_pionkow;
  16. } pole;
  17.  
  18. // lista dwukierunkowa w C++ jest zaimplementowana już w bibliotece STL
  19. // (jeśli mnie pamięć nie myli).. a jeśli nie można z niej korzystać, to trzeba
  20. // zrobić własną implementacje.. gdzieś mogę wygrzebać prawdopodobnie
  21. // implementację listy dwukierunkowej w C, którą kiedyś robiłem i działała
  22.  
  23. // potrzebna będzie lista dwukierunkowa, której elementy będą typu pole
  24.  
  25. // do listy dodajemy elementy, które zostają wczytane
  26. // z pliku z danymi wejściowymi
  27.  
  28. //////////////////////////////////////////////////////////////////////
  29. // Funkcja wykonuje przekształcenia zgodnie z ruchem w lewo
  30. // zdefiniowanym w treści zadania
  31. //////////////////////////////////////////////////////////////////////
  32. void ruch_lewo(*wsk_aktualny_element) {
  33.    if (wsk_aktualny_element.poprzedniElement == NULL) {
  34.        // jeśli nie istnieje poprzednik aktualnie badanego elementu,
  35.        // to trzeba go stworzyć
  36.        pole *nowy_element = new pole;
  37.        // nowemu elementowi przypisujemy numer pola mniejszy o jeden
  38.        // względem badanego elementu
  39.        nowy_element.numer_pola = wsk_aktualny_element.numer_pola - 1;
  40.        nowy_element.liczba_pionkow = 1;
  41.        // ustawiamy elementy w odpowiedniej relacji wzlgędem siebie
  42.        wsk_aktualny_element.poprzedniElement = &nowy_element;
  43.        nowy_element.nastepnyElement = &wsk_aktualny_element;
  44.        // jeśli użyta będzie lista z biblioteki to nie trzeba będzie
  45.        // tego wszystkiego robić ręcznie
  46.        // --
  47.        // w tym momencie wiemy też, że nie istnieje element poprzedzający
  48.        // do dopiero co stworzonego nowego elementu, więc możemy
  49.        // od razu dodać jeszcze jeden, zgodnie z ruchem w lewo
  50.        wsk_aktualny_element = &nowy_element;
  51.        pole *nowy_element = new pole;
  52.        nowy_element.numer_pola = wsk_aktualny_element.numer_pola - 1;
  53.        nowy_element.liczba_pionkow = 1;
  54.        wsk_aktualny_element.poprzedniElement = &nowy_element;
  55.        nowy_element.nastepnyElement = &wsk_aktualny_element;
  56.    }
  57.    else {
  58.        // jeśli element poprzedzający badany element istnieje...
  59.        // ... to sprawdzamy czy ma swojego poprzednika
  60.        if (wsk_aktualny_element.poprzedniElement.poprzedniElement != NULL) {
  61.            // jeśli posiada poprzednika
  62.            // to dodajemy do jego liczby pionków wartość 1
  63.            poprzedniElement = &wsk_aktualny_element.poprzedniElement.poprzedniElement;
  64.            poprzedniElement.liczba_pionkow += 1;
  65.        }
  66.        else { // jeśli nie posiada poprzednika
  67.            // to trzeba go stworzyć...
  68.            pole *nowy_element = new pole;
  69.            nowy_element.numer_pola = wsk_aktualny_element.poprzedniElement.numer_pola - 1;
  70.            nowy_element.liczba_pionkow = 1;
  71.            nowy_element.nastepnyElement = &wsk_aktualny_element.poprzedniElement;
  72.            wsk_aktualny_element.poprzedniElement.poprzedniElement = &nowy_element;
  73.        }
  74.    }
  75.    // zmniejszamy wartość liczby pionków aktualnie badanego elementu
  76.    // o jeden
  77.    wsk_aktualny_element.liczba_pionkow -= 1;
  78. }
  79.  
  80. //////////////////////////////////////////////////////////////////////
  81. // Funkcja wykonuje przekształcenia zgodnie z ruchem w prawo
  82. // zdefiniowanym w treści zadania
  83. //////////////////////////////////////////////////////////////////////
  84. void ruch_prawo(*wsk_aktualny_element) {
  85.    // jeżeli nie istnieje poprzednik dla aktualnie badanego elementu
  86.    // to trzeba go stworzyć
  87.    if (wsk_aktualny_element.poprzedniElement == NULL) {
  88.        pole *nowy_element = new pole;
  89.        nowy_element.numer_pola = wsk_aktualny_element.numer_pola - 1;
  90.        nowy_element.liczba_pionkow = -1 ;
  91.        wsk_aktualny_element.poprzedniElement = &nowy_element;
  92.        nowy_element.nastepnyElement = &wsk_aktualny_element;
  93.    }
  94.    else { // jeżeli istnieje poprzednik...
  95.        wsk_aktualny_element.poprzedniElement.liczba_pionkow -= 1;
  96.    }
  97.  
  98.    // jeżeli nie istnieje element następujący po aktualnie badanym elemencie
  99.    // to trzeba go stworzyć
  100.    if (wsk_aktualny_element.nastepnyElement == NULL) {
  101.        pole *nowy_element = new pole;
  102.        nowy_element.numer_pola = wsk_aktualny_element.numer_pola + 1;
  103.        nowy_element.liczba_pionkow = 1;
  104.        wsk_aktualny_element.nastepnyElement = &nowy_element;
  105.        nowy_element.poprzedniElement = &wsk_aktualny_element;
  106.    }
  107.    else { // jeśli istnieje następujący element...
  108.        wsk_aktualny_element.nastepnyElement.liczba_pionkow += 1;
  109.    }
  110.    // zmniejszamy wartość liczby pionków aktualnie badanego elementu
  111.    // o jeden
  112.    wsk_aktualny_element.liczba_pionkow -= 1;
  113. }
  114.  
  115. //////////////////////////////////////////////////////////////////////
  116. // Funkcja wypisująca wynik końcowy po przekształceniach
  117. //////////////////////////////////////////////////////////////////////
  118. void wypisz_wynik(lista) {
  119.    // funkcja wypisze całą zawartość listy w postaci
  120.    // a1 b1
  121.    // a2 b2
  122.    // .. ..
  123.    // aN bN
  124.    pole *wsk_aktualny_element; // wsk_aktualny element podczas wywołania
  125.                                // funkcji musi wskazywać na pierwszy
  126.                                // element listy
  127.    for(wsk_aktualny_element = &lista; \     // wsk_aktualny_element podczas
  128.                            // inicjalizacji pętli powinien wskazywać
  129.                            // na pierwszy element listy
  130.        wsk_aktualny_element.nastepnyElement != NULL; \// pętla zatrzyma się w momencie,
  131.                            // w którym element, który jest wskazywany przez
  132.                            // wsk_aktualny_element.nextElement będzie pusty
  133.                            // (nie będzie kolejnego elementu w liście)
  134.        wsk_aktualny_element = wsk_aktualny_element.nastepnyElement) {
  135.  
  136.        printf("%d %d", wsk_aktualny_element.numer_pola, \
  137.               wsk_aktualny_element.liczba_pionkow);
  138.    }
  139. }
  140.  
  141. //////////////////////////////////////////////////////////////////////
  142. // Inicjalizacja listy danymi wejściowymi
  143. //////////////////////////////////////////////////////////////////////
  144. FILE *f;                        // wskaźnik na deskryptor pliku
  145. f.open('input.txt', 'r');       // otwieramy plik do odczytu
  146. pole *lista = inicjalizuj_liste(); // tutaj trzeba użyć własnej implementacji
  147.                                // lub gotowców z bibliotek
  148. for (i=0; i<n; i++) {
  149.    int input_liczba_pierwsza, input_liczba_druga;  // deklaracja zmiennych
  150.                            // pomocniczych do odczytania danych wejściowych
  151.  
  152.    fscanf(f, "%d %d", &input_liczba_pierwsza, \    // zczytanie
  153.           &input_liczba_pierwsza);     // pary liczb z pliku wejściowego
  154.    pole *element = new pole;     // tworzenie nowego elementu typu "struct _pole"
  155.    element.numer_pola      = input_liczba_pierwsza;
  156.    element.liczba_pionkow  = input_liczba_druga;
  157.    lista.dodaj_element(&nowy_element); // metoda/funkcja dodawania nowego
  158.                                    // elementu na koniec istniejącej listy
  159. }
  160.  
  161.  
  162. // w tym momencie mamy już w pamięci wszystkie dane, których potrzebujemy
  163. // zaczynamy iterację
  164.  
  165. bool _koniec=false;      // zmienna sterująca pętlą while()
  166.  
  167. // aczkolwiek spokojnie można by tutaj zrobić pętlę nieskończoną
  168. // ponieważ wiemy w którym momencie powinniśmy skończyć
  169. while (_koniec==false) {
  170.  
  171.    pole *max_element = &lista; // zakładamy, że pierwszy element listy
  172.                                // ma największą wartość..
  173.    // iterujemy sie po całej liście w poszukiwaniu maximum
  174.    for(wsk_aktualny_element=&lista; wsk_aktualny_element.nastepnyElement != NULL \
  175.        wsk_aktualny_element=wsk_aktualny_element.nastepnyElement;) {
  176.  
  177.        // jeśli natkniemy się na wartość mniejszą niż zero, to musimy
  178.        // wykonać ruch w lewo dla następnego elementu
  179.        if (wsk_aktualny_element.liczba_pionkow < 0) {
  180.            max_element = wsk_aktualny_element.nastepnyElement;
  181.            break; // opuszczamy pętlę for i wykonujemy ruch w lewo
  182.        }
  183.        // jeśli następny element ma większą liczbe pionków
  184.        // to wyznaczamy nasz max_element i lecimy dalej
  185.        if (wsk_aktualny_element.liczba_pionkow > max_element.liczba_pionkow) {
  186.            max_element = wsk_aktualny_element;
  187.        }
  188.    }
  189.    // jeśli znalezionym maximum jest liczba pionków = 1
  190.    // oznacza to, że skończyliśmy algorytm i możemy wyjśc z pętli while
  191.    if (max_element.liczba_pionkow == 1) {
  192.        _koniec = true;
  193.        break; // wychodzimy z pętli
  194.    }
  195.    // w tym momencie mamy wyznaczone nasze maximum w tej iteracji
  196.    // (tylko jeśli nie nastąpił _koniec)
  197.    if ( _koniec == false) {
  198.        // sprawdzamy, czy poprzedzający element istnieje..
  199.        if (max_element.poprzedniElement != NULL) {
  200.            // jeśli istnieje, to sprawdzamy, czy jego liczba pionków
  201.            // jest mniejsza od zera
  202.            if (max_element.poprzedniElement.liczba_pionkow < 0) {
  203.                // jesli tak, to robimy ruch w lewo
  204.                ruch_lewo(&max_element);
  205.            }
  206.            else { // jeśli liczba pionków poprzedzającego elementu jest większa,
  207.                // lub równa zero, to lecimy z ruchem w prawo
  208.  
  209.            }
  210.        }
  211.        else { // jeśli poprzedzający element nie istnieje, to robimy ruch w prawo
  212.            ruch_prawo(&max_element);
  213.        }
  214.    }
  215. }
  216.  
  217. // w tym miejscu możemy już wyświetlić wynik końcowy
  218. wypisz_wynik(&lista);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement