试题 算法训练 跳马
资源限制
内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s
问题描述
一个8×8的棋盘上有一个马初始位置为(a,b),他想跳到(c,d),问是否可以?如果可以,最少要跳几步?
输入格式
一行四个数字a,b,c,d。
输出格式
如果跳不到,输出-1;否则输出最少跳到的步数。
样例输入
1 1 2 3
样例输出
1
数据规模和约定
0<a,b,c,d≤8且都是整数。
之前数据结构没学好,一直不知道bfs搜索的是路径最短。。。试了好久终于试出来了
由于跳马到达该点的路径并不唯一,并且马的下一步选择有多种,若是使用dfs可能会导致一条错路走到最后发现不行再倒车,所以使用bfs,由出发地向周围扩散,直到找到目标
由于bfs的搜索具有路径最短的特性,那么直接标记已经走过的路,不需要回溯进行消除标记。问题简单了很多,找到了标记,必定是最短的路。
#include<bits/stdc++.h>
using namespace std;
int pan[9][9] = { 0 };
int num=0;
struct link {
int x;
int y;
int i;
};
//bfs模拟马的运动
void bfs(int k, int x, int y, int c, int d)
{
int x_choice[4] = { -2,-1,1,2 };
int y_choice[4] = { -2,-1,1,2 };
queue<link> List;
link current = { x,y,0 };
List.push(current);
while (!List.empty())
{
link current_q = List.front();
List.pop();
pan[current_q.x][current_q.y] = 1;
if (current_q.x == c && current_q.y == d)
{
num = current_q.i;
}
for(int i=0;i<4;i++)
for (int j = 0; j < 4; j++)
{
if ((current_q.x + x_choice[i] <= 8) && (current_q.y + y_choice[j] <=8) && (current_q.x + x_choice[i] >= 1) && (current_q.y + y_choice[j] >= 1))
{
if (abs(x_choice[i]) != abs(y_choice[j]) && pan[current_q.x + x_choice[i]][current_q.y + y_choice[j]] != 1) {
List.push({ current_q.x + x_choice[i] ,current_q.y + y_choice[j],current_q.i + 1 });
}
}
}
}
}
int main()
{
int a = 0, b = 0, c = 0, d = 0;
cin >> a >> b >> c >> d;
pan[a][b] = 1;
bfs(0, a, b, c, d);
if (a == c && c == d)
cout << 0;
else
if (num != 0)
cout << num;
else
cout << -1;
}
本题题目限定其实是在1-8之间,而不是0-7
考虑出发点和终点重合的情况
代码太丑了,大火见谅,请大家指导优化