如何在矩阵

时间:2016-09-05 12:13:59

标签: java search matrix grid cells

在最近的一次采访中,他们问我这个问题:

考虑一个由单位尺寸的正方形单元组成的战场。战场上的一名士兵可以从一个小区移动到其相邻小区的所有(8个)。士兵有一把枪,他可以沿着8个可能的方向(北,东,西,南,东北,西北,东南,西南)向任何距离射击目标。还有一些细胞是防弹的,可防止子弹通过,但是士兵可以像在正常细胞一样走过它们。他可以从防弹细胞中摧毁目标,但不能从它后面的细胞中摧毁。

给定目标的位置,目标的起始位置和所有防弹单元的位置。你必须告诉最近射击点的位置,即士兵可以射击目标并最接近士兵起始位置的单元格。如果有多个这样的单元格,则输出所有单元格。

输入规格:

I)战场大小{整数对(N,M):战场将为N * M大小)

II)士兵的起始位置{整数对(i,j)}

III)目标的位置{整数对(x,y):安装目标的单元的位置}

IV)所有防弹单元的位置{整数对列表a#b:列表中的每个元素都是防弹单元的位置} *

输出规格:

整数对的顺序列表i#j(单元格)是最接近的射击点,必须遵循行方式遍历。

注意:如果输出列表包含四个射击点:4x4战场上的(2,1),(1,2),(3,2),(2,4)。 那么正确的输出将是{1#2,2#1,2#4,3#2}而不是{1#2,2#1,3#2,2#4}

示例:输入:{2,2} {2,1} {2,2} {1#1,1#2}输出:2#1

我的代码:

public class Test2 {

public static void main(String[] args) {
    int[] size = {4, 4};
    int[] startPt = {1, 1};
    int[] endPt = {4, 2};
    String[] impenetrable = {"2#2", "3#3","3#2"};
    Process(size, startPt, endPt, impenetrable);
}

public static void Process(int[] size, int[] startPt, int[] endPt, String[] impenStr) {
    //Initialize starting position.
    int x = startPt[0] - 1;
    int y = startPt[1] - 1;
    List<String> output = new ArrayList<String>();
    int count = 0;
    int[][] direction = {{x, y}, {x, y}, {x, y}, {x, y}, {x, y}, {x, y}, {x, y}, {x, y}};
    int[][] board = new int[size[0]][size[1]];

    board[startPt[0] - 1][startPt[1] - 1] = 1;
    board[endPt[0] - 1][endPt[1] - 1] = 2;

    //Impenetrable Points
    for (String p : impenStr) {
        String[] tmp = p.split("#");
        board[Integer.parseInt(tmp[0]) - 1][Integer.parseInt(tmp[1]) - 1] = 99;
    }

    System.out.println("The Board:");

    for (int m = 0; m < board.length; m++) {
        for (int n = 0; n < board.length; n++) {
            System.out.print(board[m][n] + "\t");
        }
        System.out.println();
    }

    while (output.isEmpty()) {
        output = Surroundings(direction, endPt[0], endPt[1], board);
        //for (int m = 0; m < board.length; m++) {
          //  for (int n = 0; n < board.length; n++) {
            //    if(m!=startPt[0] - 1 || n!=startPt[1] - 1){

              //  }
            //}
        //}
        direction[0][0] = direction[0][0] - 1; // up
        direction[0][1] = direction[0][1];

        direction[1][0] = direction[1][0] + 1; // Down
        direction[1][1] = direction[1][1];

        direction[2][0] = direction[2][0]; // Left
        direction[2][1] = direction[2][1] - 1;

        direction[3][0] = direction[3][0]; // right
        direction[3][1] = direction[3][1] + 1;

        direction[4][0] = direction[4][0] - 1; // NE
        direction[4][1] = direction[4][1] + 1;

        direction[5][0] = direction[5][0] + 1; // SW
        direction[5][1] = direction[5][1] - 1;

        direction[6][0] = direction[6][0] + 1; // SE
        direction[6][1] = direction[6][1] + 1;

        direction[7][0] = direction[7][0] - 1; // NW
        direction[7][1] = direction[7][1] - 1;
        count++;


        if (!output.isEmpty()) {
            break;
        }
    }

    System.out.println(Arrays.toString(output.toArray()));
}

public static List<String> Surroundings(int[][] direction, int targetX, int targetY, int[][] board) {
    String string = "";
    List<String> output = new ArrayList<String>();
    for (int i = 0; i < direction.length; i++) {
        try {
            if (board[direction[i][0]][direction[i][1]] == 99) {
                board[direction[i][0]][direction[i][1]] = 0;
            }
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        if (checkDirections(board, direction[i][0], direction[i][1], targetX - 1, targetY - 1) == true) {
            string = string + (direction[i][0] + 1) + "#" + (direction[i][1] + 1);
        }
        try {
            if (board[direction[i][0]][direction[i][1]] == 0) {
                board[direction[i][0]][direction[i][1]] = 99;
            }
        } catch (ArrayIndexOutOfBoundsException e) {
        }

        if (!string.equals("")) {
            output.add(string);
            string = "";
        }


    }
    return output;
}

public static boolean checkDirections(int[][] battleField, int x, int y, int finalX, int finalY) {
    return North(battleField, x, y, finalX, finalY) == true
            || South(battleField, x, y, finalX, finalY) == true
            || West(battleField, x, y, finalX, finalY) == true
            || East(battleField, x, y, finalX, finalY) == true
            || NE(battleField, x, y, finalX, finalY) == true
            || SE(battleField, x, y, finalX, finalY) == true
            || NW(battleField, x, y, finalX, finalY) == true
            || SW(battleField, x, y, finalX, finalY) == true;
}

public static boolean North(int[][] board, int x, int y, int targetX, int targetY) {
    if (x < 0 || x >= board.length || y < 0 || y >= board.length || board[x][y] == 99) {
        return false;
    } else if (x == targetX && y == targetY) {
        return true;
    } else {
        return North(board, x - 1, y, targetX, targetY);
    }
}

public static boolean South(int[][] board, int x, int y, int targetX, int targetY) {
    if (x < 0 || x >= board.length || y < 0 || y >= board.length || board[x][y] == 99) {
        return false;
    } else if (x == targetX && y == targetY) {
        return true;
    } else {
        return South(board, x + 1, y, targetX, targetY);
    }
}

public static boolean West(int[][] board, int x, int y, int targetX, int targetY) {
    if (x < 0 || x >= board.length || y < 0 || y >= board.length || board[x][y] == 99) {
        return false;
    } else if (x == targetX && y == targetY) {
        return true;
    } else {
        return West(board, x, y + 1, targetX, targetY);
    }
}

public static boolean East(int[][] board, int x, int y, int targetX, int targetY) {
    if (x < 0 || x >= board.length || y < 0 || y >= board.length || board[x][y] == 99) {
        return false;
    } else if (x == targetX && y == targetY) {
        return true;
    } else {
        return East(board, x, y - 1, targetX, targetY);
    }
}

public static boolean NE(int[][] board, int x, int y, int targetX, int targetY) {
    if (x < 0 || x >= board.length || y < 0 || y >= board.length || board[x][y] == 99) {
        return false;
    } else if (x == targetX && y == targetY) {
        return true;
    } else {
        return NE(board, x - 1, y + 1, targetX, targetY);
    }
}

public static boolean SW(int[][] board, int x, int y, int targetX, int targetY) {
    if (x < 0 || x >= board.length || y < 0 || y >= board.length || board[x][y] == 99) {
        return false;
    } else if (x == targetX && y == targetY) {
        return true;
    } else {
        return SW(board, x + 1, y - 1, targetX, targetY);
    }
}

public static boolean SE(int[][] board, int x, int y, int targetX, int targetY) {
    if (x < 0 || x >= board.length || y < 0 || y >= board.length || board[x][y] == 99) {
        return false;
    } else if (x == targetX && y == targetY) {
        return true;
    } else {
        return SE(board, x + 1, y + 1, targetX, targetY);
    }
}

public static boolean NW(int[][] board, int x, int y, int targetX, int targetY) {
    if (x < 0 || x >= board.length || y < 0 || y >= board.length || board[x][y] == 99) {
        return false;
    } else if (x == targetX && y == targetY) {
        return true;
    } else {
        return NW(board, x - 1, y - 1, targetX, targetY);
    }
}}

我被困的地方:

将此图像视为战场,将黄色块视为起点。

在我的代码中,对于每个循环,我继续搜索外环的元素。

我可以水平,垂直和对角地为所有块获得正确的解决方案。(图像中的蓝色块)。

但是我无法访问红色块。我如何访问它们?

1 个答案:

答案 0 :(得分:0)

目前,您的main方法在每一步都有一个固定数量(8)的单元格。这不会像每个步骤那样起作用。向外实际上会增加你应该检查的单元格数量。

考虑到您检查的单元数量非常小,最简单的解决方案可能只是检查板上的每个单元而不是向外走。您可以保持变量与目标的最小距离。

代码看起来像这样:

int minDistanceToTarget = Integer.MAX_VALUE;
for each position on the board
    if position can hit target
        if distance < minDistanceToTarget
            minDistanceToTarget = distance
            output = ""
        if distance == minDistanceToTarget
            add position to output

希望您看到它是如何工作的:只要找到可以击中目标的较近位置然后将该距离处的所有位置添加到输出,它就会重置输出。

顺便说一句,如果你将你的位置封装在Position类而不是作为第二个维存在你的数组中,我认为你的代码会更整洁。类似的东西:

enum Direction {
    N, NE, E, SE, S, SW, W, NW;

    public int getRowDelta();
    public int getColDelta();
}

class Position
    private final int row;
    private final int col;

    public Position(int row, int col);
    public int distanceTo(Position other);
    public Position move(Direction direction);
}

class Board {
    private final int width;
    private final int height;
    private final Position start;
    private final Position target;
    private final List<Position> bulletproofCells;

    public Board(String input);
    public String getOutput();
}

如果将逻辑封装在诸如此类的类中,您会发现可以删除方法中的代码重复。