/* Mon Oct 27 23:28:17 JST 2003 */ /* Tue Oct 28 00:25:32 JST 2003 */ #include #include #define FLOOR 0 #define PILLAR 1 #define CARGO 2 #define GOAL 3 #define MAN 4 int w, h; int map[9][9]; int already[9][9][4]; int gx, gy; int min = INT_MAX; void output(int cx, int cy, int mx, int my) { int x, y; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { if (x == cx && y == cy) { printf(" ? ", CARGO); } else if (x == mx && y == my) { printf(" @ ", MAN); } else if (x == gx && y == gy) { printf(" X ", GOAL); } else printf("%3d ", map[y][x]); } printf("\n"); } printf("-----\n"); } int rec(int cx, int cy, int mx, int my, int move) { int x, y, done, dist, i, j, result; int dx[4] = {0, 1, 0, -1}; int dy[4] = {1, 0, -1, 0}; int capable[4] = {0, 0, 0, 0}; #if 0 output(cx, cy, mx, my); #endif if (cx == gx && cy == gy) { return move; } map[my][mx] = (-1); for (dist = -1; ; dist--) { done = 0; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { if (map[y][x] == dist) { for (i = 0; i < 4; i++) { if (map[y+dy[i]][x+dx[i]] == FLOOR && !(y+dy[i] == cy && x+dx[i] == cx)) { map[y+dy[i]][x+dx[i]] = dist-1; done = 1; } } } } } if (!done) break; } for (i = 0; i < 4; i++) { if (map[cy+dy[i]][cx+dx[i]] < 0) { capable[i] = 1; } } for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { if (map[y][x] < 0) { map[y][x] = 0; } } } for (i = 0; i < 4; i++) { if (capable[i] && already[cy][cx][i]) { return INT_MAX; } } for (i = 0; i < 4; i++) { if (!capable[i]) continue; if (map[cy-dy[i]][cx-dx[i]] == FLOOR) { already[cy][cx][i] = 1; result = rec(cx-dx[i], cy-dy[i], cx, cy, move+1); if (result < min) min = result; already[cy][cx][i] = 0; } } return INT_MAX; } int main() { int x, y, i; int cx, cy; int mx, my; while (1) { scanf("%d %d", &w, &h); if (w == 0 && h == 0) break; w += 2; h += 2; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { if (x == 0 || y == 0 || x == w-1 || y == h-1) { map[y][x] = 1; continue; } scanf("%d", &map[y][x]); if (map[y][x] == CARGO) { cx = x; cy = y; map[y][x] = FLOOR; } if (map[y][x] == GOAL) { gx = x; gy = y; map[y][x] = FLOOR; } if (map[y][x] == MAN) { mx = x; my = y; map[y][x] = FLOOR; } for (i = 0; i < 4; i++) { already[y][x][i] = 0; } } } min = INT_MAX; rec(cx, cy, mx, my, 0); if (min == INT_MAX) printf("%d\n", -1); else printf("%d\n", min); } }