algorytm.org

Implementacja w C/C++

Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Najkrótsza droga w labiryncie - Implementacja w C/C++
Ocena użytkownikóww: *****  / 8
SłabyŚwietny
Nadesłany przez Jakub Konieczny, 20 lutego 2011 17:57
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.
Pobierz pełne rozwiązanie.

Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.

lab_1_c.cpp:
//Poszukiwanie drogi w labiryncie
//www.algorytm.org

#include <cstdio>
#include <cstring>

const char *MAPA[]={
"##########",
"# #     ##",
"# #  #   #",
"# #   #  #",
"# ### ## #",
"#     #  #",
"# # ###  #",
"# #    # #",
"#    #   #",
"##########"
};

char val[]="0123456789abcdefghijklmnoprstuvwxyz";

void rysuj(char mapa[10][10]){
    for(int y=0; y<10; y++){
        for(int x=0; x<10; x++){
            if(mapa[x][y]<0)
                printf("#");
            if(mapa[x][y]==0)
                printf(" ");
            else
                printf("%c", val[mapa[x][y]]);
        }
        printf("\n");
    }
    printf("\n");
}

bool zaznacz(char mapa[10][10]){
    // Funkcja potrzebuje mapy w której wartość 1 to punkt startowy, -1 to miejsca gdzie nie może iść
    // 0 to wolne pola
    //Wymaga ramki do okoła
    bool zmiana=false;
    int o;
    for(int y=1; y<9; y++){
        for(int x=1; x<9; x++){
            if(mapa[x][y]<0) continue; //jeśli ściana, sprawdź następny
            o=mapa[x][y]; //przed oznaczeniem
            if(mapa[x+1][y]>0) //prawo jeśli nie ma ściany, ale został odwiedzony
            if(mapa[x+1][y]+1<mapa[x][y] || mapa[x][y]==0) //i jeśli z tamtej drogi jest krócej do aktualnej,
                                                            //lub aktualna jest nieodwiedzona
                mapa[x][y]=mapa[x+1][y]+1; //oznacza tutaj odległość poprzedniej+1

            if(mapa[x-1][y]>0) //lewo
            if(mapa[x-1][y]+1<mapa[x][y] || mapa[x][y]==0)
                mapa[x][y]=mapa[x-1][y]+1;

            if(mapa[x][y+1]>0) //dół
            if(mapa[x][y+1]+1<mapa[x][y] || mapa[x][y]==0)
                mapa[x][y]=mapa[x][y+1]+1;

            if(mapa[x][y-1]>0) //góra
            if(mapa[x][y-1]+1<mapa[x][y] || mapa[x][y]==0)
                mapa[x][y]=mapa[x][y-1]+1;

            if(o!=mapa[x][y]) zmiana=true; //jeśli zaszła zmiana, ustawia na true, że była jakaś zmiana i kolejne wykonanie
                                    //może coś jeszcze zmienić
        }
    }
    return zmiana;
}

void wyczysc(char mapa[10][10],  int odX, int odY, int doX, int doY){
    //Czyszczenie dróg
    bool droga[10][10]; //przechowuje najkrótszą ścieżkę
    memset(droga, 0, 100); //czyszczenie tablicy
    while(odX!=doX || odY!=doY){ //dopóki nie dojdzie od końca do punktu początkowego
        droga[doX][doY]=true;
        //szukanie po sąsiadach najkrótszych odległości, tzn. mniejszych od aktualnej
        //wcześniejsza funkcja daje pewność, że różnice między odległościami zawsze wynoszą 1
        if(mapa[doX+1][doY]<mapa[doX][doY] && mapa[doX+1][doY]>0){
            doX++; continue;
        }
        if(mapa[doX-1][doY]<mapa[doX][doY] && mapa[doX-1][doY]>0){
            doX--; continue;
        }
        if(mapa[doX][doY+1]<mapa[doX][doY] && mapa[doX][doY+1]>0){
            doY++; continue;
        }
        if(mapa[doX][doY-1]<mapa[doX][doY] && mapa[doX][doY-1]>0){
            doY--; continue;
        }
        return; //jeśli jakimś sposobem nie ma najkrótszej drogi, przerywa
    }
    for(int y=1; y<9; y++){
        for(int x=1; x<9; x++){
            if(!droga[x][y])
                if(mapa[x][y]>0)
                    mapa[x][y]=0; //czyszczenie dłuższych dróg
        }
    }
    mapa[odX][odY]=1; //punkt startowy
}

void szukaj(int odX, int odY, int doX, int doY){
    char mapa[10][10];
    for(int i=0; i<100; i++){ //przepisanie mapy, w tym przypadku trzeba ją obrócić
        if(MAPA[i%10][i/10]=='#') //jeśli ściana
            mapa[i/10][i%10]=-1; //przypisz wartość ujemną
        else
            mapa[i/10][i%10]=0; //puste
    }
    printf("Mapa: \n");
        rysuj(mapa); //mapa bez narysowanych scieżek
    mapa[odX][odY]=1; //punkt startoey
    while(zaznacz(mapa)){ //zaznaczanie na mapie kolejno odwiedzanych pól, dopóki są jakiś zmiany, powtarza
        //rysuj(mapa);
    }
    printf("Odleglosci: \n");
    rysuj(mapa); //rysuje mapę z wyznaczonymi odległościami
    wyczysc(mapa, odX, odY, doX, doY); //pozostawia tylko najkrótszą ścieżkę
    printf("Najkrotsza: \n");
    rysuj(mapa); //rysuje mapę po oczyszczeniu
}

int main(){
    szukaj(1,1, 8,4);
    /*
        ##########
        #S#     ##
        # #  #   #
        # #   #  #
        # ### ##E#
        #     #  #
        # # ###  #
        # #    # #
        #    #   #
        ##########
    */
    return 0;
}
Komentarze
photo
+3 # Adriangfgfdgfdgfdsgf 2011-06-15 15:02
U mnie to jakoś dobrze nie działa:(
U mnie mapka się sypie, proszę o sprawdzenie poprawności algorytmu
Odpowiedz | Odpowiedz z cytatem | Cytować
Dodaj komentarz