Sample Input
e2 e4
a1 b2
b2 c3
a1 h8
a1 h7
h8 a1
b1 c3
f6 f6
Sample Output
To get from e2 to e4 takes 2 knight moves.
To get from a1 to b2 takes 4 knight moves.
To get from b2 to c3 takes 2 knight moves.
To get from a1 to h8 takes 6 knight moves.
To get from a1 to h7 takes 5 knight moves.
To get from h8 to a1 takes 6 knight moves.
To get from b1 to c3 takes 1 knight moves.
To get from f6 to f6 takes 0 knight moves.
Source::Click here
思路
给你骑士的出发位置和目标位置,求到达终点所用的最少的步数。其实就是一个模板题啦,不知道暑期集训时为啥没写对啊!
主要是理解骑士的移动规则就可以了,和中国象棋的”马走日“是一样的,然后写一个方向数组,其他的就没差了。
AC Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 10;
int sx, sy, ex,ey;
char ch1[5], ch2[5];
bool vis[MAXN][MAXN];
int dp[8][2] = {1,-2,-1,-2,2,-1,-2,-1,2,1,-2,1,1,2,-1,2};
struct node
{
int x, y;
int step;
friend bool operator < (node a, node b)
{
return a.step > b.step;
}
};
void bfs(int x1, int y1, int x2, int y2)
{
int ans = 0;
node st1, st2;
memset(vis,false,sizeof(vis));
st1.x = x1; st1.y = y1; st1.step = 0;
vis[st1.x][st1.y] = true;
priority_queue<node> qu;
qu.push(st1);
while(!qu.empty())
{
st1 = qu.top();
qu.pop();
if(st1.x==x2 && st1.y==y2)
{
ans = st1.step;
break;
}
for(int i=0; i<8; i++)
{
st2.x = st1.x + dp[i][0];
st2.y = st1.y + dp[i][1];
if(!vis[st2.x][st2.y] && st2.x<=8 && st2.x>=1 && st2.y<=8 && st2.y>=1)
{
st2.step = st1.step + 1;
vis[st2.x][st2.y] = true;
qu.push(st2);
}
}
}
printf("To get from %s to %s takes %d knight moves.\n",ch1,ch2,ans);
}
int main()
{
while(~scanf("%s %s",ch1,ch2))
{
sx = ch1[1] - '0';
sy = ch1[0] - 'a' + 1;
ex = ch2[1] - '0';
ey = ch2[0] - 'a' + 1;
bfs(sx,sy,ex,ey);
}
return 0;
}