#include <iostream>
#include <istream>
#include <sstream>
#include <vector>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <numeric>
#include <chrono>
#include <ctime>
#include <cmath>
#include <cctype>
#include <string>
#include <cstdio>
#include <iomanip>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <iterator>
using namespace std;
const int maxn = 20, maxm = 256;
char matrix[maxn][maxn];
int row, col, ngos, ret = 0, cnt = 0;
const int Dir[5][2] = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 }, {0,0} };
vector<pair<int, int>> points;
map<pair<int, int>, int> mmp;
int G[maxm][5], slen[maxm];
int dis[maxm][maxm][maxm], vis[maxm][maxm][maxm];
int sdir[3], ddir[3];
int GetID(int a, int b, int c) {
return (a << 16) | (b << 8) | c;
}
void Init() {
mmp.clear();
points.clear();
memset(G, 0, sizeof(G));
memset(sdir, 0, sizeof(sdir));
memset(ddir, 0, sizeof(ddir));
memset(dis, -1, sizeof(dis));
memset(vis, 0, sizeof(vis));
memset(slen, 0, sizeof(slen));
cnt = 0;
}
int isok(int last, int last2, int cur, int cur2) {
if (cur == cur2 || (last == cur2 && last2 == cur)) return false;
return true;
}
int bfs() {
int ret = 0;
queue<int> q;
int dStart = GetID(sdir[0], sdir[1], sdir[2]), dEnd = GetID(ddir[0], ddir[1], ddir[2]);
q.push(dStart);
dis[sdir[0]][sdir[1]][sdir[2]] = 0;
while (!q.empty()) {
int len = q.size();
for (int i = 0; i < len; i++) {
int cur = q.front();
q.pop();
int a = (cur >> 16) & 0xff, b = (cur >> 8) & 0xff, c = cur & 0xff;
if (cur == dEnd) return dis[a][b][c];
int na, nb, nc;
for (int ii = 0; ii < slen[a]; ii++) {
na = G[a][ii];
for (int jj = 0; jj < slen[b]; jj++) {
nb = G[b][jj];
if (!isok(a, b, na, nb)) continue;
for (int kk = 0; kk < slen[c]; kk++) {
nc = G[c][kk];
if (!isok(a, c, na, nc) || !isok(b, c, nb, nc)) continue;
if (dis[na][nb][nc] == -1) {
q.push(GetID(na, nb, nc));
dis[na][nb][nc] = dis[a][b][c] + 1;
}
}
}
}
}
++ret;
}
return -1;
}
int Doit(queue<int>& q, int(&d)[maxm][maxm][maxm], int flag) {
int cur = q.front();
q.pop();
int a = (cur >> 16) & 0xff, b = (cur >> 8) & 0xff, c = cur & 0xff;
int na, nb, nc;
for (int ii = 0; ii < slen[a]; ii++) {
na = G[a][ii];
for (int jj = 0; jj < slen[b]; jj++) {
nb = G[b][jj];
if (!isok(a, b, na, nb)) continue;
for (int kk = 0; kk < slen[c]; kk++) {
nc = G[c][kk];
if (!isok(a, c, na, nc) || !isok(b, c, nb, nc)) continue;
if (vis[na][nb][nc] == 0) {
q.push(GetID(na, nb, nc));
d[na][nb][nc] = d[a][b][c] + 1;
vis[na][nb][nc] = 3 ^ flag;
}
else if (vis[na][nb][nc] == flag) {
return d[na][nb][nc] + d[a][b][c];
}
}
}
}
return -1;
}
int dbfs() {
queue<int > front;
queue<int > back;
int dStart = GetID(sdir[0], sdir[1], sdir[2]), dEnd = GetID(ddir[0], ddir[1], ddir[2]);
if (dStart == dEnd) return 0;
front.push(dStart);
back.push(dEnd);
dis[sdir[0]][sdir[1]][sdir[2]] = 0;
dis[ddir[0]][ddir[1]][ddir[2]] = 1;
vis[sdir[0]][sdir[1]][sdir[2]] = 1;
vis[ddir[0]][ddir[1]][ddir[2]] = 2;
while (!front.empty() || !back.empty()) {
int len = front.size(), ret = -1;
for (int i = 0; i < len; i++) {
if ((ret = Doit(front, dis, 2)) != -1) return ret;
}
len = back.size();
for (int i = 0; i < len; i++) {
if ((ret = Doit(back, dis, 1)) != -1) return ret;
}
}
return -1;
}
int main()
{
while (cin >> col >> row >> ngos && col && row && ngos) {
Init();
cin.ignore();
for (int i = 0; i < row; i++) {
fgets(matrix[i], maxn, stdin);
for (int j = 0; j < col; j++) {
if (matrix[i][j] == '#') continue;
mmp[make_pair(i, j)] = points.size();
if (isupper(matrix[i][j])) sdir[matrix[i][j] - 'A'] = points.size();
else if (islower(matrix[i][j])) ddir[matrix[i][j] - 'a'] = points.size();
points.push_back(make_pair(i, j));
}
}
for (int i = 0; i < points.size(); i++) {
pair<int, int> temp = points[i];
for (int j = 0; j < 5; j++) {
int nx = temp.first + Dir[j][0];
int ny = temp.second + Dir[j][1];
if (nx >= 0 && nx < row && ny >= 0 && ny < col && matrix[nx][ny] != '#') {
G[i][slen[i]++] = mmp[make_pair(nx, ny)];
}
}
}
cnt = points.size();
if (ngos <= 2) { slen[cnt] = 1; G[cnt][0] = cnt; sdir[2] = ddir[2] = cnt++; }
if (ngos <= 1) { slen[cnt] = 1; G[cnt][0] = cnt; sdir[1] = ddir[1] = cnt++; }
//cout << bfs() << endl;
cout << dbfs() << endl;
}
return 0;
}
10-10
2266
07-15
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交