/* Hořící les -- program sepsal Martin Mareš */ #include #include #define MAXRS 100 int R, S; // Rozměry lesa char map[MAXRS][MAXRS]; // Mapa lesa int flame[MAXRS][MAXRS]; // Kdy se na políčko dostal oheň int fqueue[MAXRS*MAXRS][2]; // Fronta pro šíření ohně int fr, fw; // ... její čtecí a zápisový index int state[MAXRS][MAXRS+1]; // Stav pro zpětný průchod int bqueue[MAXRS*MAXRS][2]; // Fronta pro zpětný průchod int br, bw; // ... a její indexy int delta[4][2] = { {-1,0}, {1,0}, {0,-1}, {0,1} }; // Směry // Vypočteme, kdy se na které políčko dostane oheň. void fire(void) { // Políčka, kde hoří na počátku, přidáme do fronty a přiřadíme jim čas 1. for (int i=0; i= 0 && i < R && j >= 0 && j < S && map[i][j] != '#' && !flame[i][j]) { // Prázdné políčko, které ještě nehoří => označit a přidat do fronty. flame[i][j] = flame[i0][j0] + 1; fqueue[fw][0] = i; fqueue[fw][1] = j; fw++; } } } } // Zpětným průchodem hledáme nejpozdější okamžik, kdy jde lesem projít. // Využíváme přitom postup šíření ohně, který se dochoval ve frontě fqueue. void back(void) { // Pokud nikde nehořelo, les je průchozí stále. if (!fr) { puts("Les je průchozí až do konce světa."); return; } // Zjistíme, kdy se oheň rozšířil na poslední políčko. int t0 = flame[ fqueue[fr-1][0] ][ fqueue[fr-1][1] ]; int t = t0; // Políčka těsně za pravým okrajem přidáme do fronty a uzavřeme. for (int i=0; i hotovo. if (t0 == t) puts("Les je průchozí na věky věkův."); else printf("Les je průchozí až do času %d\n", t-1); return; } for (int s=0; s<4; s++) { int i = i0 + delta[s][0], j = j0 + delta[s][1]; if (i >= 0 && i < R && j >= 0 && j < S && map[i][j] != '#' && (!flame[i][j] || flame[i][j] > t) && state[i][j] != 'U') { state[i][j] = 'U'; bqueue[bw][0] = i; bqueue[bw][1] = j; bw++; } } } // Ohni, zpět! if (!t) { puts("Hej, ten les nebyl průchozí ani na začátku!"); return; } while (fr > 0 && flame[ fqueue[fr-1][0] ][ fqueue[fr-1][1] ] == t) { fr--; int i0 = fqueue[fr][0], j0 = fqueue[fr][1]; state[i0][j0] = 'O'; // Existuje-li sousední uzavřené políčko, budeme z tohoto prohledávat. for (int s=0; s<4; s++) { int i = i0 + delta[s][0], j = j0 + delta[s][1]; if (i >= 0 && i < R && i >= 0 && j <= S && state[i][j] == 'U') { state[i0][j0] = 'U'; bqueue[bw][0] = i0; bqueue[bw][1] = j0; bw++; break; } } } t--; } } int main(void) { scanf("%d%d", &R, &S); for (int i=0; i