描述
在各种棋中,棋子的走法总是一定的,如中国象棋中马走“日”。有一位小学生就想如果马能有两种走法将增加其趣味性,因此,他规定马既能按“日”走,也能如象一样走“田”字。
他的同桌平时喜欢下围棋,知道这件事后觉得很有趣,就想试一试,在一个(100×100)的围棋盘上任选两点A、B,A点放上黑子,B点放上白子,代表两匹马。棋子可以按“日”字走,也可以按“田”字走,俩人一个走黑马,一个走白马。谁用最少的步数走到左上角坐标为(1,1)的点时,谁获胜。现在他请你帮忙,给你A、B两点的坐标,想知道两个位置到(1,1)点可能的最少步数。
格式
输入格式
A、B两点的坐标。
输出格式
最少步数。
样例
输入样例
12 16
18 10
输出样例
8
9
限制
时间限制: 1000 ms
内存限制: 65536 KB
对于广搜的题目,感觉套路是这样的:题目会告诉你具体怎么走,比如这个题的走“日”和走“田”,那么你需要一个或多个数组来提前记录走法,然后用队列或者数组模拟队列将每一步都放入其中,一旦搜到结果就输出。
#include <iostream>
#include <queue>
#include <string.h>
using namespace std;
void bfs(int x, int y) {
int piece[101][101]; //棋盘步数
int que[100001][4]; //模拟队列
int dx[12]={-2,-2,-1, 1, 2, 2,2,2,1,-1,-2,-2};
int dy[12]={-1,-2,-2,-2,-2,-1,1,2,2, 2, 2, 1};
memset(piece, -1, sizeof(piece));
memset(que, 0, sizeof(que));
que[1][1] = x; //初始位置x
que[1][2] = y; //初始位置y
que[1][3] = 0; //一开始是0步
int tail=1, head=1; //相当于队列的头与尾
if (x == 1 && y == 1) { //我被这个测试点卡了一下,要是你只过了90%,可以试试
printf ("0\n");
return;
}
while (head <= tail) {
for (int i=0; i<12; i++) { //开始广搜
int tmpx = que[head][1] + dx[i]; //新的x
int tmpy = que[head][2] + dy[i]; //新的y
if (tmpx>0 && tmpx<101 && tmpy>0 && tmpy<101 && piece[tmpx][tmpy] == -1) {
piece[tmpx][tmpy] = que[head][3] + 1; //新的1步
tail++;
que[tail][1] = tmpx; //入队x
que[tail][2] = tmpy; //入队y
que[tail][3] = piece[tmpx][tmpy]; //入队步数
if (piece[1][1] > 0) { //一旦搜到就输出
printf ("%d\n", piece[1][1]);
return ;
}
}
}
head++; //开始下一轮广搜
}
}
int main()
{
int ax, ay, bx, by;
scanf ("%d %d", &ax, &ay);
scanf ("%d %d", &bx, &by);
bfs(ax, ay);
bfs(bx, by);
return 0;
}
在这里马一个一维数组的BFS经典题目抓住那头牛 ,用做对比与学习