简单的bfs,
状态表示为3个pieces的坐标,状态转移就是寻找可用的边走下去,
注意到1 2 3和3 2 1是一个坐标,也就是说3个pieces的坐标是对称的
所以将这3个数排序,以减少状态总数
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
/*
#include <FSTREAM>
ifstream fin("data.txt");
#define cin fin
*/
int n, s[3], t[3];
int g[51][51];
int color[26];
int d[51][51][51];
void bfs()
{
queue<int> q;
int c1, c2, c3, i;
q.push(s[0]);
q.push(s[1]);
q.push(s[2]);
d[s[0]][s[1]][s[2]] = 1;
while (!q.empty())
{
c1 = q.front(); q.pop();
c2 = q.front(); q.pop();
c3 = q.front(); q.pop();
if (c1==c2 && c2==c3)
{
cout << d[c1][c2][c3]-1 << endl;
return;
}
for (i=1; i<=n; i++)
{
if (g[c1][i]==g[c2][c3] && i!=c1)
{
t[0] = i;
t[1] = c2;
t[2] = c3;
sort(&t[0], &t[3]);
if (d[t[0]][t[1]][t[2]] == 0)
{
q.push(t[0]);
q.push(t[1]);
q.push(t[2]);
d[t[0]][t[1]][t[2]] = d[c1][c2][c3] + 1;
}
}
}
for (i=1; i<=n; i++)
{
if (g[c2][i]==g[c1][c3] && i!=c2)
{
t[0] = c1;
t[1] = i;
t[2] = c3;
sort(&t[0], &t[3]);
if (d[t[0]][t[1]][t[2]] == 0)
{
q.push(t[0]);
q.push(t[1]);
q.push(t[2]);
d[t[0]][t[1]][t[2]] = d[c1][c2][c3] + 1;
}
}
}
if (c2==c3)
continue;
for (i=1; i<=n; i++)
{
if (g[c3][i]==g[c1][c2] && i!=c3)
{
t[0] = c1;
t[1] = c2;
t[2] = i;
sort(&t[0], &t[3]);
if (d[t[0]][t[1]][t[2]] == 0)
{
q.push(t[0]);
q.push(t[1]);
q.push(t[2]);
d[t[0]][t[1]][t[2]] = d[c1][c2][c3] + 1;
}
}
}
}
cout << "impossible" << endl;
}
int main()
{
int i, j, cnt;
char ch;
while (cin>>n && n)
{
cin >> s[0] >> s[1] >> s[2];
sort(&s[0], &s[3]);
memset(color, 0, sizeof(color));
memset(d, 0, sizeof(d));
cnt = 0;
for (i=1; i<=n; i++)
{
for (j=1; j<=n; j++)
{
cin >> ch;
if (color[ch-'a'] == 0)
{
color[ch-'a'] = ++cnt;
}
g[i][j] = color[ch-'a'];
}
}
bfs();
}
return 0;
}