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;
}


U mnie mapka się sypie, proszę o sprawdzenie poprawności algorytmu