骑士游历问题——至少需要多少步

水水的chessboard

题目描述
国际象棋的棋盘大家应该都很熟悉了,那么给定棋盘上的两个格位,一个骑士(knight)需要几步才能从其中一个格位来到另一个格位呢?

//注意骑士沿一个3*2方格区域的对角线移动。

输入
多组测试数据。对于每组数据,包含两个输入数据,分别为国际象棋棋盘上两个格位的位置。

输出
对于每组数据,输出一行It takes (ans) steps to get from 第一个格位 to 第二个格位。

输入样例
e2 e4
a1 b2
b2 c3
输出样例
It takes 2 steps to get from e2 to e4
It takes 4 steps to get from a1 to b2
It takes 2 steps to get from b2 to c3

开始的时候还不太会回溯、搜索什么的,只知道一个DFS暴力搜……很明显这种最少步数应该用BFS的。

也算是BFS的一种经典问题,带层次的BFS。用一个last记录当前层的最后一个元素,用一个nlast记录下一层的最后一个元素。如果当前元素到了这一层的last元素这,那就表示层次加一,即到了下一层,相应的last也移动到nlast的位置。

#include<iostream>
#include<queue>
using namespace std;

typedef pair<int, int> p;

int v[10][10] = {0};
int m,n;

int nx[] = { 1, 1, 2, 2, -1, -1, -2, -2 };
int ny[] = { 2, -2, 1, -1, 2, -2, 1, -1 };

int BFS(int x, int y)
{
	int cur = 0;
	int last = 1;
	int nlast = 1;
	int steps = 0;
	queue<p> que;
	que.push(p(x, y));

	while (que.size() > 0)
	{
		p place = que.front();
		que.pop();
		cur++;

		if (place.first == m && place.second == n)
			return steps;

		v[place.first][place.second] = 1;

		for (int i = 0; i < 8; i++)
		{
			int next_x = place.first + nx[i];
			int next_y = place.second + ny[i];
			if (next_x >= 1 && next_x <= 8 && next_y >= 1 && next_y <= 8 && v[next_x][next_y] == 0)
			{
				que.push(p(next_x, next_y));
				nlast++;
			}
		}
		
		if(cur == last)
		{
			last = nlast;
			steps++;
		}
	}
}

int main()
{
	int i,j,x,y;
	char a[5],b[5]; 
	while(cin >> a >> b)
	{
		for(i = 1; i <= 10; i++)
			for(j = 1; j <= 10; j++)
				v[i][j] = 0;
		
		x = a[0] - 'a' + 1;
		y = a[1] - '0';
		m = b[0] - 'a' + 1;
		n = b[1] - '0';
		
		int steps = BFS(x, y);

		cout << "It takes " << steps << " steps to get from " << a << " to " << b << endl;
	}
	return 0;
}

还是不怎么熟悉,还是得多加练习C++和算法之类的。

    原文作者:骑士周游问题
    原文地址: https://blog.csdn.net/Ghoste_zhouxingyu/article/details/88629088
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞