每日一题之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;
}
    原文作者:骑士周游问题
    原文地址: https://blog.csdn.net/u014046022/article/details/83060164
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞