武士风度的牛 题型:求最短路径 特殊走法:棋盘马走日法

116 阅读1分钟

U230140 武士风度的牛 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题意解析

这道题有八个方向可以走,但是都只能走日字(且越界和墙不走):

image.png

样例解析

按照日字走法,我们发现到达终点的最短路是5:

image.png

解题思路

按照bfs正常写即可,在偏移量那里将走的方式修改为马走日的形式。

假设橘黄色是中心点,那八个方向分别是(走日字):

image.png

用偏移量表示为:

dx[]={-2,-1,1,2,2,1,-1,-2};

dy[]={1,2,2,1,-1,-2,-2,-1};

code

#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int, int>PII;
const int N = 200, M = N * N;
char g[N][N];
PII q[M];
int dist[N][N];
int n, m;

int dx[8] = { -2,-1,1,2,2,1,-1,-2 };
int dy[8] = { 1,2,2,1,-1,-2,-2,-1 };
int bfs(int x,int y)
{
	memset(dist,-1,sizeof dist);
	int hh = 0, tt = 0;
	q[0] = { x,y };
	dist[x][y] = 0;

	while (hh<=tt)
	{
		PII t= q[hh++];

		for (int i = 0; i < 8; i++)
		{
			int tx = t.x + dx[i], ty = t.y + dy[i];
			if (tx < 0 || tx >= n || ty < 0 || ty >= m||dist[tx][ty]!=-1||g[tx][ty]=='*')continue;
		
			if (g[tx][ty] == 'H')return dist[t.x][t.y] + 1;
			else
			{
				dist[tx][ty] = dist[t.x][t.y] + 1;
				q[++tt] = {tx,ty};
			}
		}
	}
	return -1;
}
int main()
{
	cin >> m >> n;
	
	for (int i = 0; i < n; i++)
		cin>>g[i];

     int d = 0;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			if (g[i][j] == 'K')
			{
				d = bfs(i, j);
			}
		}
	   }
	


	
	cout << d;
	return 0;
}

image.png