|
@@ -1,6 +1,6 @@
|
|
#include <cstdio>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <cstring>
|
|
-#include <queue>
|
|
|
|
|
|
+#include <queue> // Use priority queue to save your time & life.
|
|
|
|
|
|
using namespace std;
|
|
using namespace std;
|
|
|
|
|
|
@@ -8,44 +8,36 @@ const int N = 100;
|
|
const int M = 9;
|
|
const int M = 9;
|
|
const int S = 5;
|
|
const int S = 5;
|
|
|
|
|
|
-const char dx[4] = {1, 0, -1, 0};
|
|
|
|
-const char dy[4] = {0, 1, 0, -1};
|
|
|
|
|
|
+const short dx[4] = {1, 0, -1, 0};
|
|
|
|
+const short dy[4] = {0, 1, 0, -1};
|
|
|
|
|
|
char map[N][N + 1];
|
|
char map[N][N + 1];
|
|
-char snake[N][N];
|
|
|
|
-bool flag[N][N][M + 1][1 << S];
|
|
|
|
|
|
+short snake[N][N];
|
|
|
|
+bool flag[N][N][M + 1];
|
|
|
|
|
|
struct Pos {
|
|
struct Pos {
|
|
- char r;
|
|
|
|
- char c;
|
|
|
|
- char key;
|
|
|
|
- bool kill;
|
|
|
|
- char died;
|
|
|
|
|
|
+ short r;
|
|
|
|
+ short c;
|
|
|
|
+ short key;
|
|
|
|
+ short kill;
|
|
int t;
|
|
int t;
|
|
- Pos(char r = 0, char c = 0, char key = 0, bool kill = false, char died = 0,
|
|
|
|
- int t = 0)
|
|
|
|
- : r(r), c(c), key(key), kill(kill), died(died), t(t) {}
|
|
|
|
|
|
+ Pos(short r = 0, short c = 0, short key = 0, short kill = 0, int t = 0)
|
|
|
|
+ : r(r), c(c), key(key), kill(kill), t(t) {}
|
|
bool operator==(const Pos &that) const {
|
|
bool operator==(const Pos &that) const {
|
|
return this->r == that.r && this->c == that.c && this->key == that.key;
|
|
return this->r == that.r && this->c == that.c && this->key == that.key;
|
|
}
|
|
}
|
|
|
|
+ bool operator<(const Pos &that) const { return this->t > that.t; }
|
|
};
|
|
};
|
|
|
|
|
|
-char n, m;
|
|
|
|
-
|
|
|
|
-bool is_expandable(char x, char y, char key, char died) {
|
|
|
|
- if (x < 0 || n <= x || y < 0 || n <= y) return false;
|
|
|
|
- if (map[x][y] == '#' || flag[x][y][key][died]) return false;
|
|
|
|
- return true;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
int main() {
|
|
int main() {
|
|
|
|
+ int n, m;
|
|
while (scanf("%d %d", &n, &m) != EOF) {
|
|
while (scanf("%d %d", &n, &m) != EOF) {
|
|
if (n == 0 && m == 0) break;
|
|
if (n == 0 && m == 0) break;
|
|
Pos sun, tang;
|
|
Pos sun, tang;
|
|
int s = 0;
|
|
int s = 0;
|
|
- for (char i = 0; i < n; i++) {
|
|
|
|
|
|
+ for (int i = 0; i < n; i++) {
|
|
scanf("%s", map[i]);
|
|
scanf("%s", map[i]);
|
|
- for (char j = 0; j < n; j++) {
|
|
|
|
|
|
+ for (int j = 0; j < n; j++) {
|
|
if (map[i][j] == 'T') {
|
|
if (map[i][j] == 'T') {
|
|
tang.r = i;
|
|
tang.r = i;
|
|
tang.c = j;
|
|
tang.c = j;
|
|
@@ -59,12 +51,12 @@ int main() {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- queue<Pos> q;
|
|
|
|
|
|
+ priority_queue<Pos> q;
|
|
q.push(sun);
|
|
q.push(sun);
|
|
memset(flag, 0, sizeof(flag));
|
|
memset(flag, 0, sizeof(flag));
|
|
- flag[sun.r][sun.c][0][0] = true;
|
|
|
|
|
|
+ flag[sun.r][sun.c][0] = true;
|
|
while (!q.empty()) {
|
|
while (!q.empty()) {
|
|
- Pos &cur = q.front();
|
|
|
|
|
|
+ Pos cur = q.top();
|
|
q.pop();
|
|
q.pop();
|
|
if (cur == tang) {
|
|
if (cur == tang) {
|
|
tang.t = cur.t;
|
|
tang.t = cur.t;
|
|
@@ -73,6 +65,28 @@ int main() {
|
|
for (int i = 0; i < 4; i++) {
|
|
for (int i = 0; i < 4; i++) {
|
|
int nx = cur.r + dx[i];
|
|
int nx = cur.r + dx[i];
|
|
int ny = cur.c + dy[i];
|
|
int ny = cur.c + dy[i];
|
|
|
|
+ if (nx < 0 || n <= nx || ny < 0 || n <= ny) continue;
|
|
|
|
+ char grid = map[nx][ny];
|
|
|
|
+ if (grid == '#') continue;
|
|
|
|
+ if (grid == 'S') {
|
|
|
|
+ if (flag[nx][ny][cur.key]) continue;
|
|
|
|
+ if (cur.kill & (1 << snake[nx][ny]))
|
|
|
|
+ q.emplace(nx, ny, cur.key, cur.kill, cur.t + 1);
|
|
|
|
+ else
|
|
|
|
+ q.emplace(nx, ny, cur.key, cur.kill | (1 << snake[nx][ny]),
|
|
|
|
+ cur.t + 2);
|
|
|
|
+ flag[nx][ny][cur.key] = true;
|
|
|
|
+ } else {
|
|
|
|
+ if (!flag[nx][ny][cur.key]) {
|
|
|
|
+ q.emplace(nx, ny, cur.key, cur.kill, cur.t + 1);
|
|
|
|
+ flag[nx][ny][cur.key] = true;
|
|
|
|
+ }
|
|
|
|
+ if ('1' <= grid && grid <= '9' && grid - '0' == cur.key + 1 &&
|
|
|
|
+ !flag[nx][ny][grid - '0']) { // Get key
|
|
|
|
+ q.emplace(nx, ny, grid - '0', cur.kill, cur.t + 1);
|
|
|
|
+ flag[nx][ny][grid - '0'] = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (tang.t == -1)
|
|
if (tang.t == -1)
|