输入
第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
思路:
可以bfs每个骑士走到每个位置的最小步数,然后枚举棋盘的每个位置,算每个骑士步数的加和。取最小的。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
int dir[8][2] = {{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}};
map<char,int>mp;
bool vis[10][10];
int step[3][10][10];
struct Node
{
int x,y,s;
};
void init() {
for (int i = 1; i <= 8; ++i) {
char x = 'A'+ i-1;
char y = '0'+ i;
mp[x] = i;
mp[y] = i;
}
}
bool check(Node t) {
if (t.x >= 1 && t.x <= 8 && t.y >= 1 && t.y <= 8 && vis[t.x][t.y] == 0) {
return true;
}
else return false;
}
void bfs(int k, Node t) {
memset(vis,0,sizeof(vis));
memset(step[k],0,sizeof(step[k]));
vis[t.x][t.y] = 1;
queue<Node>q;
q.push(t);
while(!q.empty()) {
auto now = q.front();
q.pop();
Node tmp;
for (int i = 0; i < 8; ++i) {
tmp.x = now.x + dir[i][0];
tmp.y = now.y + dir[i][1];
tmp.s = now.s + 1;
if (check(tmp)) {
vis[tmp.x][tmp.y] = 1;
step[k][tmp.x][tmp.y] = tmp.s;
q.push(tmp);
}
}
}
}
void solve(vector<Node>& A) {
for (int i = 0; i < (int)A.size(); ++i) {
Node tmp = A[i];
bfs(i,tmp);
}
int res = maxn;
for (int i = 1; i <= 8; ++i) {
for (int j = 1; j <= 8; ++j) {
int tmp = 0;
for (int k = 0; k < 3; ++k) {
tmp += step[k][i][j];
}
res = min(res,tmp);
}
}
cout << res << endl;
}
int main() {
int t;
cin >> t;
init();
while(t--) {
string s;
vector<Node>A;
for (int i = 0; i < 3; ++i) {
cin >> s;
Node t;
t.x = mp[s[0]];
t.y = mp[s[1]];
t.s = 0;
A.push_back(t);
}
solve(A);
}
return 0;
}