题目介绍
最近练题的过程中,遇到这么一种情况:在一个二维矩阵中,有一个小的固定的图形,需要移动这个小的图形到达某个指定的位置,求最短距离。
图形化的题目看起来长下面这个样子:
其中:
- S:表示起始位置
- O:表示目标位置,
S
接触到 O
为终止条件
- W:表示水域,是不可通过的区域
这个图还没看明白题目的话,不要紧。看下面这张图!!!
对滴!就是90坦克大战的简易版(暴露年龄,哈哈~),只不过我们题目的设定没那么复杂,坦克也不能转向。
下面就来看看代码吧!
代码实现
以下代码仅表述核心算法逻辑,请忽略变量初始化等问题哈~
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
| import java.util.ArrayDeque; import java.util.ArrayList; import java.util.List; import java.util.Queue;
public class MoveArray { static int R, C; static char[][] MAP;
static List<int[]> BODY; static int[][] MOVE = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
static Queue<List<int[]>> QUEUE; static List<int[]> NEXT_ITEMS; static boolean[][] VISITED;
static int ANS;
public static void main(String[] args) { initData(); ANS = resolve(); System.out.println(ANS); }
private static void initData() { MAP = new char[R][C]; VISITED = new boolean[R][C]; QUEUE = new ArrayDeque<>(); NEXT_ITEMS = new ArrayList<>(); ANS = 0;
QUEUE.offer(BODY); for (int[] cell : BODY) { VISITED[cell[0]][cell[1]] = true; } }
private static int resolve() { while (!QUEUE.isEmpty()) { ANS++; while (!QUEUE.isEmpty()) { List<int[]> body = QUEUE.poll(); for (int[] shift : MOVE) { boolean[] result = how(body, shift); if (!result[0]) { continue; } if (result[1]) { return ANS; } List<int[]> moved = new ArrayList<>(); for (int[] cell : body) { int nx = cell[0] + shift[0]; int ny = cell[1] + shift[1];
moved.add(new int[]{nx, ny}); VISITED[nx][ny] = true; } NEXT_ITEMS.add(moved); } } QUEUE.addAll(NEXT_ITEMS); NEXT_ITEMS.clear(); } return -1; }
private static boolean[] how(List<int[]> body, int[] shift) { boolean couldGo = false; boolean touch = false;
for (int[] cell : body) { int nx = cell[0] + shift[0]; int ny = cell[1] + shift[1]; if (nx >= 0 && nx < R && ny >= 0 && ny < C) { if ('O' == MAP[nx][ny]) { touch = true; } if ('W' == MAP[nx][ny]) { couldGo = false; break; } if (!VISITED[nx][ny]) { couldGo = true; } } else { couldGo = false; break; } }
return new boolean[]{couldGo, touch}; } }
|
最后
以上算法就是对此类问题的个人理解,当然这个算法思路在其他类似的模型中也能适用。如果您有更好的解法思路,请留言交流哈~
欢迎关注我的公众号 须弥零一,跟我一起学习IT知识。
如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !