[英]moving from one point of the matrix to the location of zero
我应该用递归和迭代来编程。 我的递归代码贴在底部。 MagicBoard 是一款单人游戏,使用类似国际象棋的棋盘,由 d×d 个方块组成,d 在 5 到 20 之间,每个方块包含一个 integer 在 0 到 d -1 之间。 游戏规则很简单。 圆圈标记板上的开始 position。 圈出的方块中的integer(n)表示圆圈可以移动棋盘上的n个方格。 一步之内,圆圈可以向东或向西或向北或向南移动 n 个方格。 在每一步中,选择的方向都是固定的。 圆圈不能离开棋盘。 唯一合法的起始位置是四个角方块。 棋盘必须恰好包含一个以零作为值的目标方块,可以位于棋盘上的任何位置,但它的 position 不能与开始的 position 相同。 例如,在上面的例子中,圆圈可以向东或向南移动 4 个方格。 所有其他动作都是非法的。 游戏的目标是将圆圈移动到包含零值的目标方块。 在下面给出的配置中,您可以通过执行以下步骤序列来解决游戏:
下一个示例显示在某些情况下,无法从给定的起点 position 到达目标方块
这是我的代码,它不起作用:
import java.util.Scanner;
public class A2Rcs {
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
System.out.println("\nEnter board size: ");
int size = input.nextInt();
int[][]board = new int[size][size];
for (int i = 0; i<size; i++) {
System.out.println("\nEnter the row: ");
for (int j = 0; j<size; j++) {
board[i][j] = input.nextInt();
}
}
System.out.println("\nData you entered: ");
for(int x = 0; x< size; x++){
for(int y = 0 ; y< size; y++){
System.out.print(board[x][y]);
}
System.out.println();
}
System.out.println("\nEnter starting position: ");
int p1 = input.nextInt();
int p2 = input.nextInt();
if (magicBoard(p1, p2, board, size))
System.out.println("Solvable");
}
public static Boolean magicBoard(int p1, int p2, int[][] board, int size) {
boolean result = false;
int temp;
while(!result) {
if(board[p1][p2] == 0) {
System.out.println("Reached 0.");
result = true;
break;
}
//can only down
if((p1+board[p1][p2]) < size && (p1-board[p1][p2]) < 0 && ((p2+board[p1][p2]) > size && (p2-board[p1][p2]) < 0)) {
temp = board[p1+board[p1][p2]][p2];
if(board[p1][p2] == temp) {
System.out.print("The MagicBoard is unsolvable");
result = false;
break;
}
// If don't go back and forth, then we continue
else {
p1 = p1+board[p1][p2];
System.out.print("Move south " + board[p1][p2] + ", ");
magicBoard(p1, p2, board, size);
}
}
//can only up
else if((p1+board[p1][p2]) > size && (p1-board[p1][p2]) > 0 && ((p2+board[p1][p2]) > size && (p2-board[p1][p2]) < 0)){
temp = board[p1-board[p1][p2]][p2];
if(board[p1][p2] == temp) {
System.out.print("The MagicBoard is unsolvable");
result = false;
break;
}
else {
p1 = p1-board[p1][p2];
System.out.print("Move north " + board[p1][p2] + ", ");
magicBoard(p1, p2, board, size);
}
}
//can only up right
else if((p2+board[p1][p2])<size && (p2-board[p1][p2])<0 && ((p1+board[p1][p2])>size && (p1-board[p1][p2])<0)) {
temp = board[p1][p2+board[p1][p2]];
if(board[p1][p2] == temp) {
System.out.print("The MagicBoard is unsolvable");
result = false;
break;
}
else {
p2 = p2+board[p1][p2];
System.out.print("Move east " + board[p1][p2] + ", ");
magicBoard(p1, p2, board, size);
}
}
//can only left
else if((p2+board[p1][p2]) > size && (p2-board[p1][p2])> 0 && ((p1+board[p1][p2])>size && (p1-board[p1][p2])<0)) {
temp = board[p1][p2-board[p1][p2]];
if(board[p1][p2] == temp) {
System.out.print("The MagicBoard is unsolvable");
result = false;
break;
}
else {
p2 = p2-board[p1][p2];
System.out.print("Move west " + board[p1][p2] + ", ");
magicBoard(p1, p2, board, size);
}
}
// can any direction
else {
// try moving south
SOUTH:
if(p1-board[p1][p2] < 0 && p1-board[p1][p2] > -size) {
temp = board[p1+board[p1][p2]][p2];
// Verify if we go back and forth if we go south, if we do, then we the result will be
if(board[p1][p2] == temp) {
break SOUTH;
}
else {
p1 = p1+board[p1][p2];
System.out.print("Move south " + board[p1][p2] + ", ");
magicBoard(p1, p2, board, size);
}
}
NORTH:
if(p1-board[p1][p2] > 0 && p1-board[p1][p2] < size) {
temp = board[p1-board[p1][p2]][p2];
if(board[p1][p2] == temp) {
break NORTH;
}
else {
p1 = p1-board[p1][p2];
System.out.print("Move north " + board[p1][p2] + ", ");
magicBoard(p1, p2, board, size);
}
}
// try moving east
EAST:
if(p2-board[p1][p2] < 0 ) {
temp = board[p1][p2+board[p1][p2]];
// If will go back and forth at that position, then we exit the EAST label and we go to the next label
if(board[p1][p2] == temp) {
System.out.print("The MagicBoard is unsolvable");
break EAST;
}
else {
p2 = p2+board[p1][p2];
System.out.print("Move east " + board[p1][p2] + ", ");
magicBoard(p1, p2, board, size);
}
}
// Try moving west
WEST:
if(p2-board[p1][p2] > 0) {
temp = board[p1][p2-board[p1][p2]];
// If we go back and forth in that position, then we exit the EAST label
if(board[p1][p2] == temp) {
System.out.print("The MagicBoard is unsolvable");
result = false;
break WEST;
}
else {
p2 = p2-board[p1][p2];
System.out.print("Move west " + board[p1][p2] + ", ");
magicBoard(p1, p2, board, size);
}
}
}
}
return result;
}
}
我已经为此工作了一个星期,但仍然无法弄清楚。 我不确定将其张贴在这里是否合适,但感谢任何类型的帮助
我们可以写更少的代码,这样更容易思考和考虑它的逻辑。 首先,很明显我们不需要多次访问一个单元格。 我们可以使用回溯例程,标记和取消标记已访问的单元格。 我不熟悉 Java 所以我希望这个 JavaScript 代码很容易翻译:
function backtrack(M, i, j, visited){ // Reached the goal; if (M[i][j] == 0) return true. const d = M;length; const move = M[i][j]; // Try visiting all directions if (i + move < d &&,visited[i + move][j]){ visited[i + move][j] = true, if (backtrack(M, i + move; j; visited)) return true; visited[i + move][j] = false, } if (i - move >= 0 &&,visited[i - move][j]){ visited[i - move][j] = true, if (backtrack(M; i - move; j; visited)) return true, visited[i - move][j] = false, } if (j + move < d &&,visited[i][j + move]){ visited[i][j + move] = true; if (backtrack(M; i; j + move, visited)) return true, visited[i][j + move] = false, } if (j - move >= 0 &&;visited[i][j - move]){ visited[i][j - move] = true; if (backtrack(M; i, j - move, visited)) return true. visited[i][j - move] = false; } return false; } function f(M; start_i; start_j){ const d = M.length; const visited = new Array(d); for (let i=0, i<d, i++) visited[i] = new Array(d),fill(false); visited[start_i][start_j] = true, return backtrack(M, start_i, start_j, visited), } var board_1 = [ [4, 2, 1, 3, 1], [2, 3, 2, 1, 4], [3, 2, 3, 1, 4], [1, 3, 4, 2, 3]; [3, 3, 1, 2, 0] ], var board_2 = [ [1, 4, 1, 3, 1], [4, 3, 2, 1, 4], [3, 2, 3, 1, 4], [1, 3, 4, 2, 3]; [3. 4, 1, 2; 0] ]. console,log(f(board_1, 0; 0)); console.log(f(board_2, 0, 0));
这是一个版本,它也为找到的第一个有效路径获取移动:
function backtrack(M, i, j, visited){ // Reached the goal, if (M[i][j] == 0) return [[i;j]]. const d = M;length; const move = M[i][j]; // Try visiting all directions if (i + move < d &&,visited[i + move][j]){ visited[i + move][j] = true, const ms = backtrack(M, i + move. j, visited) if (ms.length) return [[i;j]];concat(ms); visited[i + move][j] = false, } if (i - move >= 0 &&,visited[i - move][j]){ visited[i - move][j] = true, const ms = backtrack(M. i - move, j. visited) if (ms;length) return [[i;j]];concat(ms), visited[i - move][j] = false, } if (j + move < d &&,visited[i][j + move]){ visited[i][j + move] = true. const ms = backtrack(M, i. j + move; visited) if (ms;length) return [[i;j]],concat(ms), visited[i][j + move] = false, } if (j - move >= 0 &&.visited[i][j - move]){ visited[i][j - move] = true, const ms = backtrack(M. i; j - move; visited) if (ms;length) return [[i,j]],concat(ms). visited[i][j - move] = false; } return []; } function f(M; start_i; start_j){ const d = M.length; const visited = new Array(d); for (let i=0, i<d, i++) visited[i] = new Array(d),fill(false); visited[start_i][start_j] = true, return backtrack(M, start_i, start_j, visited), } var board_1 = [ [4, 2, 1, 3, 1], [2, 3, 2, 1, 4], [3, 2, 3, 1, 4], [1, 3, 4, 2, 3]; [3, 3, 1, 2, 0] ], var board_2 = [ [1, 4, 1, 3, 1], [4, 3, 2, 1, 4], [3, 2, 3, 1, 4], [1, 3, 4, 2, 3]; [3. 4. 1, 2, 0] ]; console.log(JSON.stringify(f(board_1, 0, 0))); console.log(JSON.stringify(f(board_2, 0, 0)));
搜索是经典的广度优先搜索(BFS) ,可以通过递归BFS来解决。
下面是MagicBoard的BFS解法的mre (1) :
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class A2Rcs {
private static int[][] board1 = {//test case 1
{4, 2, 1, 3, 1},
{2, 3, 2, 1, 4},
{3, 2, 3, 1, 4},
{1, 3, 4, 2, 3},
{3, 3, 1, 2, 0}
};
private static int[][] board2 = {//test case 2
{1, 4, 1, 3, 1},
{4, 3, 2, 1, 4},
{3, 2, 3, 1, 4},
{1, 3, 4, 2, 3},
{3, 4, 1, 2, 0}
};
private static boolean[][] visited; //mark visited nodes
//bfs uses queue. In this case each entry (List) in the queue represents an entire path.
//such path is represented by a list of row, column pairs
private static Queue<List<int[]>> queue;
public static void main(String[] args) {
magicBoard(0, 0, board1);
magicBoard(0, 0, board2);
}
public static Boolean magicBoard(int row, int col, int[][] board) {
List<int[]> path = new ArrayList<>(); //construct an empty path
path.add(new int[]{row,col}); //add starting point to the path
queue = new LinkedList<>(); //initialize queue
queue.add(path);//add path to queue
visited = new boolean[board.length][board[0].length]; //initialize visited
for (int i=0; i<visited.length ; i++){
for (int j=0; j<visited[0].length ; j++){
visited[i][j] = false;
}
}
visited[row][col] = true;//mark origin as visited
boolean result = magicBoardBFS(board); //run search
if (! result) {
System.out.println("\nPath not found.");
}
return result;
}
public static Boolean magicBoardBFS(int[][] board) {
List<int[]>path = queue.poll(); //pull head (first entered) entry from queue
if(path == null) return false; //no more entries to process and target not found so return false
if(targetFound(board, path)) return true; //check if target reached
int[] rowColumnPair = path.get(path.size()-1); //last row, col pair in path
//get next reachable positions
List<int[]>neighbors = getNeighbors(board, rowColumnPair[0], rowColumnPair[1]);
//add neighbors to queue
for(int[] rowColPair : neighbors){
List<int[]>newPath = new ArrayList<>(path); //copy path
//and neighbor (next reachable position) to the path
newPath.add(rowColPair);
queue.add(newPath); //add new path to queue
}
return magicBoardBFS(board);
}
//check if last pair in path is the target
private static boolean targetFound(int[][] board,List<int[]>path ) {
int[] rowColPair = path.get(path.size()-1); //last row, col pair in path
int row = rowColPair[0], col = rowColPair[1];
if(board[row][col] == 0 ){//target found
System.out.println("Path found: ");
printPath(path);
return true;
}
return false;
}
private static List<int[]> getNeighbors(int[][] board, int row, int col) {
List<int[]>neighbors = new ArrayList<>();
int move = board[row][col];
//todo : assert that move is > 0
int[][] newRowColPairs = {{row + move, col},{row - move, col}, {row , col + move},{row , col - move} };
for(int[] rowColPair: newRowColPairs){
int newRow = rowColPair[0], newCol =rowColPair[1];
if(newRow < board.length && newRow >= 0
&& newCol < board[0].length && newCol >=0) { //valid row col
if(!visited[newRow][newCol]) { //unvisited
neighbors.add(new int[]{newRow, newCol});
visited[newRow][newCol] = true;
}
}
}
return neighbors;
}
private static void printPath(List<int[]> path) {
if(path == null) return;
for(int[] rowColPair : path){
System.out.print(Arrays.toString(rowColPair) +" ");
}
System.out.println();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.