参考了刘汝佳老师的代码,但没有对空格编号。优点是写代码和调试时更为直观,但需要开较大的vis数组。
#include<iostream>
#include<string>
#include<cassert>
#include<algorithm>
#include<map>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<set>
#include<queue>
using namespace std;
struct pos
{
int x;
int y;
pos(int x=0,int y=0):x(x),y(y){}
pos(const pos& p) {
x = p.x;
y = p.y;
}
};
const int maxn = 16;
int grid[maxn][maxn];
map<char, pos>ori;
map<char, pos>fin;
pos s[3], t[3];
int vis[maxn * maxn][maxn * maxn][maxn * maxn];
int w, h, n;
pos operator+(const pos& p1, const pos& p2)
{
return pos(p1.x + p2.x, p1.y + p2.y);
}
bool operator==(const pos& p1,const pos& p2)
{
return p1.x == p2.x && p1.y == p2.y;
}
pos dir[5] = { {0,0}, {-1,0},{0,1},{1,0},{0,-1} };
pos G[maxn * maxn][5];
int deg[maxn * maxn];
inline int postoith(const pos& p)
{
return p.x * w + p.y;
}
void read_grid(int w,int h)
{
memset(G, 0, sizeof(G));
memset(deg, 0, sizeof(deg));
for (int i = 0; i < 3; ++i)
{
s[i].x = s[i].y = t[i].x = t[i].y = 0;
}
getchar();
for (int i = 0; i < h; ++i)
{
char temp[20];
fgets(temp, 20, stdin);
for (int j = 0; j < w; ++j)
{
char input = temp[j];
if (input == '#' || input == ' ')
grid[i][j] = input;
else if (islower(input))
{
s[input - 'a'] = pos(i, j);
grid[i][j] = ' ';
}
else if (isupper(input))
{
t[input - 'A'] = pos(i, j);
grid[i][j] = ' ';
}
}
}
for (int i = 0; i < h; ++i)
{
for (int j = 0; j < w; ++j)
{
if (grid[i][j] == ' ')
{
pos c(i, j);
int k2 = 0;
for (int k = 0; k < 5; ++k)
{
pos t = c + dir[k];
if (grid[t.x][t.y] == ' ')
G[i * w + j][k2++] = t;
}
deg[i * w + j] = k2;
}
}
}
deg[0] = 1;
}
bool conflict(const int a, const int b, const int a2, const int b2)
{
return a2 == b2 || (a == b2 && b == a2);
}
int bfs()
{
memset(vis, -1, sizeof(vis));
int a = postoith(s[0]), b = postoith(s[1]), c = postoith(s[2]);
vis[a][b][c] = 0;
int code = (a << 16) + (b << 8) + c;
queue<int>q;
q.push(code);
while (!q.empty())
{
code = q.front(); q.pop();
c = code & ((1 << 8) - 1), b = (code >> 8) & ((1 << 8) - 1), a = (code >> 16) & ((1 << 8) - 1);
pos pa(a / w, a % w), pb(b / w, b % w), pc(c / w, c % w);
if (pa == t[0] && pb == t[1] && pc == t[2])
{
return vis[postoith(t[0])][postoith(t[1])][postoith(t[2])];
}
int dega = deg[a];
int degb = deg[b];
int degc = deg[c];
for (int i = 0; i < dega; ++i)
{
pos pa2 = G[a][i];
int a2 = postoith(pa2);
for (int j = 0; j < degb; ++j)
{
pos pb2 = G[b][j];
int b2 = postoith(pb2);
if (conflict(a, b, a2, b2))
continue;
for (int k = 0; k < degc; ++k)
{
pos pc2 = G[c][k];
int c2 = postoith(pc2);
if (a == a2 && b == b2 && c == c2)continue;
if (-1 == vis[a2][b2][c2] && !conflict(a, c, a2, c2) && (!conflict(b, c, b2, c2) || n==1))
{
vis[a2][b2][c2] = vis[a][b][c] + 1;
q.push((a2 << 16) + (b2 << 8) + c2);
}
}
}
}
}
return -1;
}
int main()
{
//freopen("input.txt", "r", stdin);// freopen("output2.txt", "w", stdout);
while (scanf("%d%d%d",&w,&h,&n) && w != 0 && h != 0 && n != 0)
{
read_grid(w, h);
printf("%d\n", bfs());
}
}