所以我一直在研究以下问题:
我埋了我的蓝宝石然后开始走路。我总是走进去 罗盘方向后的直线(N,S,E,W)。当我 停了下来,我转了90度并继续走路。我可能有 越过我的道路,但我不记得了。以下是米数 我走向各个方向。我现在迷路了,必须放弃这个 当我寻找出路时记录。我把这张便条放在了 摇滚在我的最后位置。也许一些幸运的冒险家会解码 我的笔记和回溯我的步骤来赚取宝藏。不幸, 没有关于废墟中发现纸币的记录。代替, 你必须写一个程序来寻找宝藏。输入第一个 line包含两个整数X Y,表示行数和 废墟中的列。最多20行50列。下一个X. 线条显示空间的网格图。句号“。”是空方格。一个 hash“#”是一块巨石,标志着一个无法进入的方块。 下一行有一个整数N,即直路径的计数 走着。最多20条路径。最后一行包含N个整数 用空格分隔,显示连续的路径长度.5 10
####........#
。#... ##。#
...#...#
#### 8 2 4 2 2 2 5 2 1输出您的程序必须打印相同的地图,包括蓝宝石(S)和最终的位置标记的消息(F)的位置。此外,标记每个转折点 连续的小写字母(如果使用相同的点更多 不止一次,打印信件以便转弯。)只有一个 遵循列表中路径长度的路由。
####b.e.a..f#
。#... ##。#
c.d#S.Fg#
#
我已经制作了一个递归方法,从迷宫的每个开放位置开始检查每个方向,直到找到解决方案,但问题的输出需要是转弯的迷宫。
问题是,当我使用递归解决方案并编辑实际的char [] []映射时,它永远不会知道哪条路径会导致实际完成,因此它将创建如下输出:
... d d
.....
cbabc
... d d
但我希望它只显示一条路径,如下所示:
... d
.....
.. ABC
.....
这是我不完整的解决方案:
import java.util.Scanner;
public class SapphireSearch {
private static int rs; // Row Size
private static int cs; // Column Size
private static int sr; // Save row (saves solution row)
private static int sc; // Save col (saves solution col)
private static Direction sd; // Save direction (saves solution dir)
private static char[][] map; // the maze to traverse
private static int n; // number of turns
private static int[] go; // length of the turns
public static void main(String[] args) {
getInput();
for (int r = 0; r < rs; r++)
for (int c = 0; c < cs; c++)
for (Direction d : Direction.values())
solve(sr = r, sc = c, sd = d, 0, false);
}
public static void solve(int r, int c, Direction d, int start,
boolean printing) {
if (isSolid(r, c))
return;
if (printing) {
if (start == 0)
map[r][c] = 'S';
else
map[r][c] = (char) (start - 1 + 'a');
if (start == n) {
map[r][c] = 'F';
return;
}
}
if (start == n - 1 && !printing) {
solve(sr, sc, sd, 0, true);
printArray(map);
System.exit(0);
}
int count = 0;
while (start < go.length && count < go[start]) {
count++;
r += d.dr;
c += d.dc;
if (isSolid(r, c))
return;
}
for (Direction t : d.turn())
solve(r, c, t, start + 1, printing);
}
public static boolean isSolid(int r, int c) {
return map[r][c] == '#';
}
public static void printArray(char[][] o) {
for (int r = 0; r < o.length; r++) {
for (int c = 0; c < o[r].length; c++)
System.out.print(o[r][c]);
System.out.println();
}
}
private static void getInput() {
Scanner s = new Scanner(System.in);
rs = s.nextInt();
cs = s.nextInt();
s.nextLine(); // clear buffer
map = new char[rs][cs];
for (int r = 0; r < rs; r++) {
int c = 0;
char[] f = s.nextLine().trim().toCharArray();
for (char t : f)
map[r][c++] = t;
}
n = s.nextInt();
go = new int[n];
for (int i = 0; i < n; i++)
go[i] = s.nextInt();
}
}
enum Direction {
// deltaR, deltaC
up(-1, 0), down(1, 0), left(0, -1), right(0, 1);
public int dr;
public int dc;
private Direction(int dr, int dc) {
this.dr = dr;
this.dc = dc;
}
public Direction[] turn() {
Direction[] out = new Direction[2];
switch (this) {
case up:
case down:
out[0] = left;
out[1] = right;
break;
case left:
case right:
out[0] = up;
out[1] = down;
}
return out;
}
}
问题是:在我的递归求解算法的基础上,打印解决方案路径的最佳方法是什么(它不会打印出它尝试采用的每个路径)?
答案 0 :(得分:0)
你需要在进行递归搜索时建立你的转弯列表(我只是为了简单而列出这里的方向,但你也可以存储一个带有坐标的对象)。
如果路径为(N,E,N,W,S),则在退出时保存该路径。
要做到这一点,保留部分列表到目前为止,每次递归调用COPY到目前为止列表并添加到它。
即:
名词
NE nw失败
NEN nes失败
NENW
等
最后,您可以返回已完成的解决方案,或者如果您需要处理多个解决方案,则可以将完成的解决方案列入最终结果列表。
关键步骤是复制列表到目前为止,以便递归分支不会相互干扰。