-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathKnightWalk.java
132 lines (106 loc) · 3.99 KB
/
KnightWalk.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package algorithms.graph.bfs;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.*;
public class KnightWalk {
public static void main(String[] args) {
run(System.in, System.out);
}
public static void run(InputStream in, OutputStream out) {
Scanner scanner = new Scanner(in);
PrintStream printer = new PrintStream(out, true);
int t = scanner.nextInt();
while (t-- > 0) {
int n = scanner.nextInt();
int m = scanner.nextInt();
Point s = new Point(scanner.nextInt(), scanner.nextInt());
Point d = new Point(scanner.nextInt(), scanner.nextInt());
int moves = getMinMoves(n, m, s, d);
printer.println(moves);
}
}
private static int getMinMoves(int maxX, int maxY, Point s, Point d) {
Queue<Pair<Point, Integer>> queue = new LinkedList<>();
queue.add(new Pair<>(s, 0));
boolean[][] visit = new boolean[maxX][maxY];
visit[s.x - 1][s.y - 1] = true;
//System.out.println("d: " + d);
HashSet<Point> targets = new HashSet<>();
while (!queue.isEmpty()) {
Pair<Point, Integer> current = queue.poll();
//System.out.println("current: " + current);
if (current.left.equals(d)) {
return current.right;
}
targets.clear();
for (Point t : targets(targets, maxX, maxY, current.left)) {
if (!visit[t.x - 1][t.y - 1]) {
visit[t.x - 1][t.y - 1] = true;
queue.add(new Pair<>(t, current.right + 1));
}
}
}
//System.out.println("not found, s: " + s);
return -1;
}
public static Set<Point> targets(Set<Point> res, int maxX, int maxY, Point s) {
if (s.x + 1 <= maxX && s.y + 2 <= maxY) res.add(new Point(s.x + 1, s.y + 2));
if (s.x + 1 <= maxX && s.y - 2 > 0) res.add(new Point(s.x + 1, s.y - 2));
if (s.x + 2 <= maxX && s.y + 1 <= maxY) res.add(new Point(s.x + 2, s.y + 1));
if (s.x + 2 <= maxX && s.y - 1 > 0) res.add(new Point(s.x + 2, s.y - 1));
if (s.x - 1 > 0 && s.y + 2 <= maxY) res.add(new Point(s.x - 1, s.y + 2));
if (s.x - 1 > 0 && s.y - 2 > 0) res.add(new Point(s.x - 1, s.y - 2));
if (s.x - 2 > 0 && s.y + 1 <= maxY) res.add(new Point(s.x - 2, s.y + 1));
if (s.x - 2 > 0 && s.y - 1 > 0) res.add(new Point(s.x - 2, s.y - 1));
return res;
}
public static class Pair<L, R> {
public final L left;
public final R right;
public Pair(L left, R right) {
this.left = left;
this.right = right;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pair<?, ?> pair = (Pair<?, ?>) o;
return Objects.equals(left, pair.left) &&
Objects.equals(right, pair.right);
}
@Override
public int hashCode() {
return Objects.hash(left, right);
}
@Override
public String toString() {
return "Pair(" + left + ", " + right + ')';
}
}
public static class Point {
public final int x;
public final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
return x == point.x &&
y == point.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
@Override
public String toString() {
return "Point(" + x + ", " + y + ')';
}
}
}