题目描述
有一个n*m的棋盘(1<n,m<=400),在某个点上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步
输入格式
一行四个数据,棋盘的大小和马的坐标
输出格式
一个n*m的矩阵,代表马到达某个点最少要走几步(左对齐,宽5格,不能到达则输出-1)
输入输出样例
输入 #1
3 3 3 1 1
输出 #1
0 3 2
3 -1 1
2 1 4
import java.util.*;
public class Main {
public static void main(String[] args) {
Main m = new Main();
m.handleInput();
}
int n = 0;
int m = 0;
int[][] a = new int[410][410];
int[] aa = new int[] { 2, 1, 2, -1, -2, -1, -2, 1 };
int[] bb = new int[] { 1, 2, -1, -2, -1, 2, 1, -2 };
public void handleInput() {
Scanner in = new Scanner(System.in);
int x = 0, y = 0;
if (in.hasNext()) {
n = in.nextInt();
m = in.nextInt();
x = in.nextInt();
y = in.nextInt();
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
a[i][j] = -1;
}
}
dfs(x, y, 0);
a[x][y] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
System.out.printf("%-5d", a[i][j]);
}
System.out.println();
}
}
public void dfs(int x, int y, int t) {
if (t > 200) { // DFS不加剪枝的话可以加阈值,约200左右。没有的话会TLE。
return;
}
a[x][y] = t;
for (int i = 0; i < 8; i++) {
if (x + aa[i] >= 1 && y + bb[i] >= 1 && x + aa[i] <= n && y + bb[i] <= m
&& (a[x + aa[i]][y + bb[i]] == -1 || a[x + aa[i]][y + bb[i]] > t + 1)) { // 未走过的的格子,或者新的路线的步数较短就重新赋值
dfs(x + aa[i], y + bb[i], t + 1);
}
}
}
}
BFS
import java.util.*;
public class Main {
public static void main(String[] args) {
Main m = new Main();
m.sf();
}
int x, y, n, m, x0, y0;
int[][] a = new int[405][405];
int[] b = new int[5005];
Queue<Integer> qx = new LinkedList<Integer>();
Queue<Integer> qy = new LinkedList<Integer>();
int pos[][] = { { -2, -1 }, { -1, -2 }, { 1, -2 }, { -2, 1 }, { -1, 2 }, { 2, -1 }, { 1, 2 }, { 2, 1 } };
public void sf() {
Scanner in = new Scanner(System.in);
if (in.hasNext()) {
n = in.nextInt();
m = in.nextInt();
x = in.nextInt();
y = in.nextInt();
}
in.close();
for (int i = 0; i < 405; i++) {
for (int j = 0; j < 405; j++) {
a[i][j] = -1;
}
}
a[x][y] = 0;
qx.offer(x);
qy.offer(y);
while (qx.size() > 0) {
x0 = qx.poll();
y0 = qy.poll();
qx.peek();
qy.peek();
for (int i = 0; i < 8; i++) {
if (x0 + pos[i][0] >= 1 && x0 + pos[i][0] <= n && y0 + pos[i][1] >= 1 && y0 + pos[i][1] <= m
&& a[x0 + pos[i][0]][y0 + pos[i][1]] == -1) {
qx.offer(x0 + pos[i][0]);
qy.offer(y0 + pos[i][1]);
a[x0 + pos[i][0]][y0 + pos[i][1]] = a[x0][y0] + 1;
}
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
System.out.printf("%-5d", a[i][j]);
}
System.out.println();
}
}
}
BFS
import java.util.*;
public class Main {
public static void main(String[] args) {
Main m = new Main();
m.handleInput();
}
int n = 0;
int m = 0;
int x1 = 0, y1 = 0;
int[][] a = new int[405][405];
int[][] b = new int[405][405];
int[] aa = new int[] { 1, -1, 2, -2, 1, -1, 2, -2 };
int[] bb = new int[] { 2, -2, 1, -1, -2, 2, -1, 1 };
public void handleInput() {
Scanner in = new Scanner(System.in);
if (in.hasNext()) {
n = in.nextInt();
m = in.nextInt();
x1 = in.nextInt();
y1 = in.nextInt();
}
in.close();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
a[i][j] = -1;
}
}
a[x1][y1] = 0;
dfs(x1, y1);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
System.out.printf("%-5d", a[i][j]);
}
System.out.println();
}
}
Queue<Node> queue = new LinkedList<Main.Node>();
public void dfs(int x, int y) {
Node node;
Node n1 = new Node(x, y); // 这里用quene.offer(new Node(x,y)); 居然超时 ,这样就 AC
queue.offer(n1);
while (!queue.isEmpty()) {
node = queue.poll();
queue.peek();
for (int i = 0; i < 8; i++) {
if (node.x + aa[i] >= 1 && node.y + bb[i] >= 1 && node.x + aa[i] <= n && node.y + bb[i] <= m
&& a[node.x + aa[i]][node.y + bb[i]] == -1) {
queue.offer(new Node(node.x + aa[i], node.y + bb[i]));
a[node.x + aa[i]][node.y + bb[i]] = a[node.x][node.y] + 1;
}
}
}
}
class Node {
int x, y;
public Node(int x, int y) {
this.x = x;
this.y = y;
}
}
}