题目描述
有一个 n×m 的棋盘,在某个点 (x,y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。
输入格式
输入只有一行四个整数,分别为 n,m,x,y。
输出格式
一个 n×m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 -1)。
输入输出样例
输入 #1
3 3 1 1
输出 #1
0 3 2
3 -1 1
2 1 4
说明/提示
数据规模与约定
对于全部的测试点,保证 1≤x≤n≤40,1≤y≤m≤400。
解题思路:本题的马和象棋里的走法相似,按‘日’来走,所以画图分析的话有八种走法,由于要输出到每个位置的步数,这就需要广度优先遍历来地"毯式查找"。最后对不能到达的点标记为-1。
理论成立代码如下:
import java.util.*;
public class Main {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
solution s = new solution(n, m);
s.starx = sc.nextInt();
s.stary = sc.nextInt();
s.bfs();
s.print();
}
}
class solution
{
int a[][];//地图
int M;
int N;//边界
int starx,stary;//起始点
int fx[],fy[];//探索规则
solution(int m, int n)
{
a = new int[m + 1][n + 1];//本题起点(1,1)
M = m;
N = n;
int x[] = {2, -2, -2, 2, 1, -1, -1, 1};
int y[] = {1, -1, 1, -1, 2, 2, -2, -2};//八个方向
fx = x;
fy = y;
}
public void bfs()
{
bfs(starx, stary);
}
private void bfs(int xx, int yy)
{
Queue<Integer> qux = new LinkedList<>();
Queue<Integer> quy = new LinkedList<>();//储存坐标
qux.offer(xx);
quy.offer(yy);
int fxx,fyy;
while(!qux.isEmpty())
{
xx = qux.poll();
yy = quy.poll();
for(int i = 0;i < 8;i++)
{
fxx = xx + fx[i];
fyy = yy + fy[i];//新遍历方向
if(fxx > 0 && fxx <= M && fyy > 0 && fyy <= N && a[fxx][fyy] == 0 && !(fxx == starx && fyy == stary ))
{//新点要求没有被遍历过,且不是起点
a[fxx][fyy] = a[xx][yy] + 1;//新点+1
qux.offer(fxx);
quy.offer(fyy);//存入
}
}
}
}
public void print()
{
for(int i = 1;i <= M;i++)
{
for(int j = 1;j <= N;j++)
{
if(!(i == starx && j == stary) && a[i][j] == 0)
a[i][j] = -1;//没有遍历的点就是不能到达的点
System.out.print(a[i][j] + " ");//输出,注意要跟四个空格
}
System.out.println();
}
}
}