#include <stdio.h> #define INF (1 << 31 - 1) #define MAX (100 + 1) #define CA 1 #define GA 2 int rows, columns; char map[MAX][MAX]; int rowOfCA, columnOfCA; int rowOfGA, columnOfGA; int rowOfFortress, columnOfFortress; struct MOVE{ int row; int column; int days; }; MOVE queue[MAX * MAX]; int head, tail; int daysOfCA[MAX][MAX]; int daysOfGA[MAX][MAX]; int directions[8][2] = { {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1} }; void setDays(int army, int row, int column, int days){ if (army == CA) daysOfCA[row][column] = days; if (army == GA) daysOfGA[row][column] = days; } void move(int army){ head = 0; tail = 0; MOVE push; if (army == CA){ push.row = rowOfCA; push.column = columnOfCA; } if (army == GA){ push.row = rowOfGA; push.column = columnOfGA; } push.days = 0; queue[tail++] = push; setDays(army, push.row, push.column, push.days); while (head < tail){ MOVE pop = queue[head++]; int indexOfDirection; for (indexOfDirection = 0; indexOfDirection < 8; indexOfDirection++){ int row, column; row = pop.row + directions[indexOfDirection][0]; column = pop.column + directions[indexOfDirection][1]; if (row < 0 || row >= rows || column < 0 || column >= columns || ( army == CA && daysOfCA[row][column] != -1 ) || ( army == GA && daysOfGA[row][column] != -1 ) || map[row][column] == '#' || map[row][column] == '*') continue; push.row = row; push.column = column; push.days = pop.days + 1; queue[tail++] = push; setDays(army, push.row, push.column, push.days); char cha = map[row][column]; if (cha >= 'A' && cha <= 'Z'){ for (row = 0; row < rows; row++){ for (column = 0; column < columns; column++){ if (map[row][column] != cha || ( army == CA && daysOfCA[row][column] != -1 ) || ( army == GA && daysOfGA[row][column] != -1 ) ) continue; push.row = row; push.column = column; push.days = pop.days + 1; queue[tail++] = push; setDays(army, push.row, push.column, push.days); }//end of for column }//end of for row }//end of if (cha >= 'A' && cha <= 'Z') }//end of indexOfDirection }//end of while (head < tail) } int main() { scanf("%d %d", &rows, &columns); int row, column; for (row = 0; row < rows; row++){ scanf("%s", map[row]); for (column = 0; map[row][column] != '\0'; column++){ if (map[row][column] == '$'){ rowOfCA = row; columnOfCA = column; continue; } if (map[row][column] == '!'){ rowOfGA = row; columnOfGA = column; continue; } if (map[row][column] == '*'){ rowOfFortress = row; columnOfFortress = column; } } } for (row = 0; row < rows; row++){ for (column = 0; column < columns; column++){ daysOfCA[row][column] = -1; daysOfGA[row][column] = -1; } } move(CA); move(GA); int result = INF; int indexOfDirection; for (indexOfDirection = 0; indexOfDirection < 8; indexOfDirection++){ row = rowOfFortress + directions[indexOfDirection][0]; column = columnOfFortress + directions[indexOfDirection][1]; if (row < 0 || row >= rows || column < 0 || column >= columns || daysOfCA[row][column] == -1 || daysOfGA[row][column] == -1) continue; int maxDays = daysOfCA[row][column] > daysOfGA[row][column] ? daysOfCA[row][column] : daysOfGA[row][column]; if (maxDays < result) result = maxDays; } if (result == INF) printf("Impossible"); else printf("%d", result + 1); return 0; }