#include #include #include #include #define RED 1 #define GREEN 2 #define BLUE 4 #define YELLOW 8 using namespace std; struct tile { int distances[16]; char type; }; struct command { int distanceSoFar; int keys; int x; int y; }; tile** array; int width; int height; int shortestExitDistance; deque commands; bool canEnter(int keys, char tileType) { if (tileType == '#') return false; if (tileType == 'R') return (keys & RED); if (tileType == 'G') return (keys & GREEN); if (tileType == 'B') return (keys & BLUE); if (tileType == 'Y') return (keys & YELLOW); return true; } void flood(int distanceSoFar, int keys, int x, int y) { array[x][y].distances[keys] = distanceSoFar + 1; //cout << "tile: " << array[x][y].type << ", keys: " << keys << endl; if ((array[x][y].type == 'r') && ((keys & RED) == 0)) { command cmd; cmd.distanceSoFar = distanceSoFar /*+ 1*/; cmd.keys = keys | RED; cmd.x = x; cmd.y = y; commands.push_back(cmd); //cout << "red key gained, previous keys: " << keys << endl; } if ((array[x][y].type == 'g') && ((keys & GREEN) == 0)) { command cmd; cmd.distanceSoFar = distanceSoFar /*+ 1*/; cmd.keys = keys | GREEN; cmd.x = x; cmd.y = y; commands.push_back(cmd); //cout << "green key gained, previous keys: " << keys << endl; } if ((array[x][y].type == 'b') && ((keys & BLUE) == 0)) { command cmd; cmd.distanceSoFar = distanceSoFar /*+ 1*/; cmd.keys = keys | BLUE; cmd.x = x; cmd.y = y; commands.push_back(cmd); //cout << "blue key gained, previous keys: " << keys << endl; } if ((array[x][y].type == 'y') && ((keys & YELLOW) == 0)) { command cmd; cmd.distanceSoFar = distanceSoFar /*+ 1*/; cmd.keys = keys | YELLOW; cmd.x = x; cmd.y = y; commands.push_back(cmd); //cout << "yellow key gained, previous keys: " << keys << endl; } //zkontrolovat, jestli jsme nechytli exit if ((array[x][y].type == 'X') && (distanceSoFar + 1 < shortestExitDistance)) { shortestExitDistance = distanceSoFar /*+ 1*/; } //left if ((x > 0) && canEnter(keys, array[x-1][y].type) && (array[x-1][y].distances[keys] > distanceSoFar + 1)) { flood(distanceSoFar + 1, keys, x-1, y); } //right if ((x < width - 1) && canEnter(keys, array[x+1][y].type) && (array[x+1][y].distances[keys] > distanceSoFar + 1)) { flood(distanceSoFar + 1, keys, x+1, y); } //up if ((y > 0) && canEnter(keys, array[x][y-1].type) && (array[x][y-1].distances[keys] > distanceSoFar + 1)) { flood(distanceSoFar + 1, keys, x, y-1); } //down if ((y < height - 1) && canEnter(keys, array[x][y+1].type) && (array[x][y+1].distances[keys] > distanceSoFar + 1)) { flood(distanceSoFar + 1, keys, x, y+1); } } int main() { for (;;) { int startX; int startY; shortestExitDistance = 2000000000; cin >> width; cin >> height; if ((width == 0) && (height == 0)) { break; } array = new tile*[width]; for (int i=0; i< width; i++) { array[i] = new tile[height]; for (int j=0; j< height; j++) { char c; cin >> c; if (c == '*') { startX = i; startY = j; } array[i][j].type = c; for (int k=0; k<16; k++) { array[i][j].distances[k] = 2000000000; } } } commands.clear(); flood(0, 0, startX, startY); while (!commands.empty()) { //cout << "key flooding" << endl; command cmd = commands.front(); commands.pop_front(); flood(cmd.distanceSoFar, cmd.keys, cmd.x, cmd.y); } if (shortestExitDistance >= 2000000000) { cout << "The poor student is trapped!" << endl; } else { cout << "Escape possible in " << shortestExitDistance << " steps." << endl; } /*for (int i=0; i< width; i++) { for (int j=0; j< height; j++) { cout << array[i][j]; } cout << endl; }*/ } return 0; }