【题目描述】
爱与愁大神坐在公交车上无聊,于是玩起了手机。一款奇怪的游戏进入了爱与愁大神的眼帘:***(游戏名被打上了马赛克)。这个游戏类似象棋,但是只有黑白马各一匹,在点(x1,y1)(x1,y1)和(x2,y2)(x2,y2)上。它们得从点(x1,y1)(x1,y1)和(x2,y2)(x2,y2)走到(1,1)(1,1)。这个游戏与普通象棋不同的地方是:马可以走“日”,也可以像象走“田”。现在爱与愁大神想知道两匹马到(1,1)(1,1)的最少步数,你能帮他解决这个问题么?
【输入格式】
第1行:两个整数x1, y1x1,y1
第2行:两个整数x2, y2x2,y2
【输出格式】
第1行:黑马到1,11,1的步数
第2行:白马到1,11,1的步数
【说明/提示】
对于100\%100%数据:x1,y1,x2,y2 \le 20x1,y1,x2,y2≤20
分析
看到这道题一下子想到bfs,没错,就是bfs
不过要同时解决两匹马
思路一:进行两次bfs
也不是不行,不过写起来有点麻烦(比如要重置数组)
思路二:从(1,1)反向bfs
一个预处理的思路,只需要搜一遍
下面附上思路二的代码
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
int dis[50][50];
int x1[15] = {0,1,1,-1,-1,2,2,-2,-2,2,2,-2,-2};
int y1[15] = {0,2,-2,2,-2,1,-1,1,-1,2,-2,-2,2};
struct Point
{
int x,y,step;
};
void bfs()
{
memset(dis,-1,sizeof(dis));
queue<Point> q;
q.push(Point{1,1,0});
dis[1][1] = 0;
while(!q.empty())
{
int x = q.front().x,y = q.front().y,step = q.front().step;
q.pop();
for(int i = 1;i <= 12;i++)
{
int nx = x + x1[i];
int ny = y + y1[i];
if(nx < 1 || nx > 50 || ny < 1 || ny > 50)continue;
if(dis[nx][ny] != -1)continue;
dis[nx][ny] = step + 1;
q.push((Point){nx,ny,step + 1});
}
}
}
int main()
{
bfs();
int x,y;
cin >> x >> y;
cout << dis[x][y] << endl;
cin >> x >> y;
cout << dis[x][y] << endl;
return 0;
}