第一题:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
//输入
int n = scanner.nextInt();
scanner.nextLine();
int row = scanner.nextInt();
scanner.nextLine();
//用于存储亲属关系的map<son-father>
HashMap<Integer, Integer> relation = new HashMap<>();
for (int i = 0; i < row; i++) {
String s = scanner.nextLine();
String[] split = s.split("\\s+");
int father = Integer.parseInt(split[0]);
for (int j = 1; j < split.length; j++) {
int son = Integer.parseInt(split[j]);
relation.put(son, father);
}
}
int m1 = scanner.nextInt();
int m2 = scanner.nextInt();
List<Integer> m1List, m2List;
m1List = new ArrayList<>();
m2List = new ArrayList<>();
getList(m1, relation, m1List);
getList(m2, relation, m2List);
int res = calculateDis(m1List, m2List);
System.out.println(res);
}
}
private static int calculateDis(List<Integer> m1List, List<Integer> m2List) {
for (int i = 0; i < m1List.size(); i++) {
Integer num1 = m1List.get(i);
for (int j = 0; j < m2List.size(); j++) {
Integer num2 = m2List.get(j);
if(num1.equals(num2)){
return i+j;
}
}
}
return -1;
}
private static void getList(int m, HashMap<Integer, Integer> relation, List<Integer> list) {
list.add(m);
if (relation.containsKey(m)) {
getList(relation.get(m), relation, list);
}
}
第二题:
static int[] dx = {0, -1, 0, 1};
static int[] dy = {1, 0, -1, 0};
static boolean[] direction = {false, true, false, true};//上下定义为true,横向定义为false
private static int getShortDis(char[][] grid, int[] start, int[] end) {
int m = grid.length, n = grid[0].length;
boolean[][] visited = new boolean[m][n];
//按照距离升序排列
PriorityQueue<Node> nodes = new PriorityQueue<>((a, b) -> {
return a.dis - b.dis;
});
//添加初始节点
nodes.add(new Node(start[0], start[1], 0, null));
while (!nodes.isEmpty()) {
Node poll = nodes.poll();
//已经遍历过则跳过
if (visited[poll.x][poll.y]) continue;
visited[poll.x][poll.y] = true;
//如果途中找到了结果直接返回
if (poll.x == end[0] && poll.y == end[1]) return poll.dis;
for (int i = 0; i < 4; i++) {
int numSteps = 0;
int x = poll.x+dx[i], y = poll.y+dy[i];
//如果发生方向的转变需要额外增加1步
if (poll.isUpDown != null && poll.isUpDown != direction[i]) {
numSteps++;
}
//搜索目标结果
while (x >= 0 && x < m && y >= 0 && y < n && (grid[x ][y ] == 'B' || grid[x][y ] == 'E')) {
numSteps++;
//如果已访问则不参与排序
if (!visited[x][y]) nodes.add(new Node(x, y, poll.dis + numSteps, i == 1 || i == 3));
x+=dx[i];
y+=dy[i];
}
}
}
return -1;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int row = scanner.nextInt();
int col = scanner.nextInt();
scanner.nextLine();
char[][] grid = new char[row][col];
int[] start = new int[2];
int[] end = new int[2];
for (int i = 0; i < row; i++) {
String s = scanner.nextLine();
for (int j = 0; j < col; j++) {
grid[i][j] = s.charAt(j);
if (grid[i][j] == 'S') {
start[0] = i;
start[1] = j;
} else if (grid[i][j] == 'E') {
end[0] = i;
end[1] = j;
}
}
}
System.out.println(getShortDis(grid, start, end));
}
}
static class Node {
int x, y, dis;
Boolean isUpDown;
public Node(int x, int y, int dis, Boolean isUpDown) {
this.x = x;
this.y = y;
this.dis = dis;
this.isUpDown = isUpDown;
}
}
第三题
static int[] dx = {1, -1, 0, 0};
static int[] dy = {0, 0, 1, -1};
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int m = scanner.nextInt();
int n = scanner.nextInt();
int begin_x = scanner.nextInt() - 1;
int begin_y = scanner.nextInt() - 1;
int[][] grid = new int[m][n];
for (int i = 0; i < m; i++) {
scanner.nextLine();
for (int j = 0; j < n; j++) {
grid[i][j] = scanner.nextInt();
}
}
PriorityQueue<Node> queue = new PriorityQueue<>((a, b) -> {
if (a.dis == b.dis) {
if (a.x == b.x) {
return a.y - b.y;
}
return a.x - b.x;
}
return a.dis - b.dis;
});
Node begin = new Node(begin_x, begin_y, 0);
queue.add(begin);
boolean[][] visited = new boolean[m][n];
Direction[][] direction = new Direction[m][n];//记录方向的数组 0123分别表示上左右下
while (!queue.isEmpty()) {
Node poll = queue.poll();
if (visited[poll.x][poll.y]) continue;
if (grid[poll.x][poll.y] == 1 && (direction[poll.x][poll.y].y == poll.y)) {//只能从竖直方向进入
Deque<Integer> path = getPath(direction, begin_x, begin_y, poll.x, poll.y);
System.out.println(path.toString());
return;
}
visited[poll.x][poll.y] = true;
for (int i = 0; i < 4; i++) {
//计算步数
int numSteps = 0;
int x = poll.x + dx[i], y = poll.y + dy[i];
while (x >= 0 && y >= 0 && x < m && y < n && (grid[x][y] == 0 || grid[x][y] == 1)) {
numSteps++;
if(!visited[x][y]){
direction[x][y] = new Direction(poll.x, poll.y);
Node node = new Node(x, y, numSteps + poll.dis);
queue.add(node);
}
x += dx[i];
y += dy[i];
}
}
}
System.out.println(-1 + " " + -1);
}
}
private static Deque<Integer> getPath(Direction[][] direction, int begin_x, int begin_y, int end_x, int end_y) {
Deque<Integer> res = new LinkedList<>();
int x = end_x, y = end_y;
res.push(end_y + 1);
res.push(end_x + 1);
while (x != begin_x || y != begin_y) {
Direction dir = direction[x][y];
int cur_x = dir.x, cur_y = dir.y;
while (x != cur_x || y != cur_y) {
if (x < cur_x) {
x++;
} else if (y < cur_y) {
y++;
} else if (x > cur_x) {
x--;
} else {
y--;
}
res.push(y + 1);
res.push(x + 1);
}
x = dir.x;
y = dir.y;
}
return res;
}
static class Node {
int x, y, dis;
public Node(int x, int y, int dis) {
this.x = x;
this.y = y;
this.dis = dis;
}
}
static class Direction {
int x;
int y;
public Direction(int x, int y) {
this.x = x;
this.y = y;
}
}
9.21华为笔试第二题
X代表不能走,S代表驿站,可以切换为马或者兵(需要耗费1步),驿站代表可以切换为兵或者马,马走日字,兵走上下左右,.代表正常道路,问从0,0到(m-1,n-1)所使用的最小步数
static char[][] grid;
static int m, n;
static boolean[][] usedHorse;
static boolean[][] usedSoldier;
static int[][] horseDirect = new int[][]{{1, 2}, {1, -2}, {-1, 2}, {-1, -2}, {-2, 1}, {-2, -1}, {2, 1}, {2, -1}};
static int[][] soldierDirect = new int[][]{{0, 1}, {0, -1}, {-1, 0}, {1, 0}};
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
m = scanner.nextInt();
n = scanner.nextInt();
scanner.nextLine();
grid = new char[m][n];
for (int i = 0; i < m; i++) {
String s = scanner.nextLine();
for (int j = 0; j < n; j++) {
grid[i][j] = s.charAt(j);
}
}
usedHorse = new boolean[m][n];
usedSoldier = new boolean[m][n];
PriorityQueue<Node> nodes = new PriorityQueue<>((a, b) -> {
return a.dis - b.dis;
});
if (grid[0][0] == 'S') {
nodes.add(new Node(0, 0, 0, true));
nodes.add(new Node(0, 0, 1, false));
} else if (grid[0][0] == '.') {
nodes.add(new Node(0, 0, 0, true));
} else {
System.out.println(-1);
return;
}
while (!nodes.isEmpty()) {
Node poll = nodes.poll();
int curX = poll.x, curY = poll.y;
boolean curState = poll.isSoldier;
if (usedSoldier[curX][curY] && curState||(usedHorse[curX][curY]&&!curState)) continue;
System.out.println("<"+curX+","+curY+">-->"+curState+"-->"+poll.dis);
if (curState) {
usedSoldier[curX][curY] = true;
} else {
usedHorse[curX][curY] = true;
}
if (curX == m - 1 && curY == n - 1) {
System.out.println(poll.dis);
return;
}
if (curState) {
for (int[] dir : soldierDirect) {
int step = 0;
int x = dir[0] + curX, y = dir[1] + curY;
while (isValid(x, y) && grid[x][y] != 'X') {
step++;
if (grid[x][y] == 'S' && !usedHorse[x][y]) {
nodes.add(new Node(x, y, poll.dis + step + 1, false));
}
if (!usedSoldier[x][y]) nodes.add(new Node(x, y, poll.dis + step, true));
x += dir[0];
y += dir[1];
}
}
} else {
for (int[] dir : horseDirect) {
int step = 0;
int x = dir[0] + curX, y = dir[1] + curY;
while (isValid(x, y) && grid[x][y] != 'X') {
step++;
if (grid[x][y] == 'S' && !usedSoldier[x][y]) {
nodes.add(new Node(x, y, poll.dis + step + 1, true));
}
if (!usedHorse[x][y]) nodes.add(new Node(x, y, poll.dis + step, false));
x += dir[0];
y += dir[1];
}
}
}
}
System.out.println(-1);
}
}
static boolean isValid(int x, int y) {
return x >= 0 && y >= 0 && x < m && y < n;
}
static class Node {
int x, y, dis;
boolean isSoldier;
public Node(int m, int n, int dis, boolean isSoldier) {
this.x = m;
this.y = n;
this.dis = dis;
this.isSoldier = isSoldier;
}
}
测试输入
9 9
.........
.....XXX.
.....X.X.
.....X.X.
.....X.XS
XXXXXX.XX
.........
.........
.........
<0,0>-->true-->0
<0,1>-->true-->1
<1,0>-->true-->1
<0,2>-->true-->2
<1,1>-->true-->2
<2,0>-->true-->2
<1,2>-->true-->3
<2,1>-->true-->3
<3,0>-->true-->3
<0,3>-->true-->3
<0,4>-->true-->4
<2,2>-->true-->4
<1,3>-->true-->4
<3,1>-->true-->4
<4,0>-->true-->4
<2,3>-->true-->5
<1,4>-->true-->5
<3,2>-->true-->5
<4,1>-->true-->5
<0,5>-->true-->5
<4,2>-->true-->6
<2,4>-->true-->6
<3,3>-->true-->6
<0,6>-->true-->6
<3,4>-->true-->7
<4,3>-->true-->7
<0,7>-->true-->7
<4,4>-->true-->8
<0,8>-->true-->8
<1,8>-->true-->9
<2,8>-->true-->10
<3,8>-->true-->11
<4,8>-->true-->12
<4,8>-->false-->13
<5,6>-->false-->14
<3,6>-->false-->14
<6,7>-->false-->14
<8,6>-->false-->15
<2,4>-->false-->15
<7,7>-->false-->15
<7,5>-->false-->15
<4,4>-->false-->15
<2,8>-->false-->15
<6,4>-->false-->15
<6,8>-->false-->15
<4,6>-->false-->15
<8,8>-->false-->15
15