时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
小Hi:小Ho你会下国际象棋么?
小Ho:应该算会吧,我知道每个棋子的移动方式,马走日象飞田什么的…
小Hi:象飞田那是中国象棋啦!
小Ho:哦,对。国际象棋好像是走斜线来着。
小Hi:不过马走日倒是对了。国际象棋中的马一般叫做骑士,关于它有个很有意思的问题。
小Ho:什么啊?
小Hi:骑士巡游问题,简单来说就是关于在棋盘上放置若干个骑士,然后探究移动这些骑士是否能满足一定的而要求。举个例子啊:一个骑士从起始点开始,能否经过棋盘上所有的格子再回到起点。
小Ho:哦,看上去好像很难的样子。
小Hi:其实也还好了。简单一点的比如棋盘上有3个骑士,能否通过若干次移动走到一起。
小Ho:能够么?
小Hi:当然能够了。由于骑士特殊的移动方式,放置在任何一个初始位置的骑士,都可以通过若干次移动到达棋盘上任意一个位置。
小Ho:那么只要选定一个位置,把它们全部移动过去就好了是吧?
小Hi:是的,那么这里又有另一个问题了:要选择哪一个位置汇合,使得3个骑士行动的总次数最少?
小Ho:嗯,这个好像不是很难,让我想一想。
提示:骑士问题
输入
第1行:1个正整数t,表示数据组数,2≤t≤10。
第2..t+1行:用空格隔开的3个坐标, 每个坐标由2个字符AB组成,A为’A’~’H’的大写字母,B为’1’~’8’的数字,表示3个棋子的初始位置。
输出
第1..t行:每行1个数字,第i行表示第i组数据中3个棋子移动到同一格的最小行动步数。
样例输入
2
A1 A1 A1
B2 D3 F4
样例输出
0
2
#include "iostream"
#include "stdio.h"
#include "queue"
#include "utility"
#include "string.h"
using namespace std;
int t;
int initx[10];
int inity[10];
int step[4][9][9];
queue< pair<int, int> > q;
const int dx[] = {1, 2, 2, 1, -1, -2, -2, -1};
const int dy[] = {2, 1, -1, -2, -2, -1, 1, 2};
void bfs(int k, int x, int y)
{
memset(step[k], -1, sizeof(step[k]));
step[k][x][y] = 0;
pair<int,int> p;
p.first = x;
p.second = y;
q.push(p);
while(!q.empty())
{
pair<int,int> newp = q.front();
int now_x = newp.first;
int now_y = newp.second;
q.pop();
for(int i=0; i<8; i++)
{
int next_x = now_x + dx[i];
int next_y = now_y + dy[i];
if(next_x >= 1 && next_y >= 1 && next_x <= 8 && next_y<= 8 && step[k][next_x][next_y] == -1)
{
step[k][next_x][next_y] = step[k][now_x][now_y] + 1;
pair<int,int> tmp;
tmp.first = next_x;
tmp.second = next_y;
q.push(tmp);
}
}
}
}
int solve()
{
for(int i=1; i<=3; i++)
bfs(i, initx[i], inity[i]);
int min = 10000000;
for(int x=1; x<=8; x++)
for(int y=1; y<=8; y++)
{
int sum = 0;
for(int j=1; j<=3; j++)
sum += step[j][x][y];
if(sum < min)
min = sum;
}
return min;
}
int main()
{
cin >> t;
char a;
int b;
for(int i=0; i<t; i++)
{
for(int j=1; j<=3; j++)
{
cin >> a >> b;
initx[j] = a - 'A' + 1;
inity[j] = b;
}
cout << solve() << endl;
}
return 0;
}