每日一題之hiho1308 騎士問題 (bfs)
阿新 • • 發佈:2018-11-19
輸入
第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;
}