1. 程式人生 > >每日一題之hiho1308 騎士問題 (bfs)

每日一題之hiho1308 騎士問題 (bfs)

輸入
第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; }