我正在尝试编写一个函数,它得到一个MxN大小的板,其中有一列和一行,其中放置了皇后。然后我想看看女王是否受到了威胁。通常情况下,我会取这一行,并检查它的任何其他皇后,同样的列和对角线使用的循环。然而,这里有一个微小的变化,在板上也有墙可以保护女王的安全,即使在同一排中还有一个:
* * Q X * Q
* * X * * *
* Q X X Q *
Q * X Q Q *其中Q是皇后,X是墙,*是空瓷砖。在0,2的位置上的女王没有受到威胁,即使在那一排中还有一个。
另外,整个板被保存在一个2d数组中,其中皇后被赋予1的int值,墙壁是-1,空格是0。
我的想法是翻过整排,如果某个地方有女王,那么我应该找一堵墙,从那个位置一直到我正在看的皇后,再找一堵墙。不过,在我的女王之后还有第二部分。
我试着想做个总结,但那也不太管用。有人对如何实现这一点有任何想法吗?(如果威胁返回true;如果不受威胁返回false;)
编辑:这是我的代码
`public static boolean isQueenThreatened(int[][] board, int row, int col){
boolean safe=true;
for(int j = 0; j < col & safe ; j++){
if(board[row][j]==1) {
for (int i = j+1 ; i<col ; i++ ) {
if(board[row][i]!=-1) safe = false;
}
}
}
for(int j = col+1; j < board[row].length & safe ; j++){
if(board[row][j]==1) {
for (int i = j+1 ; i<board[row].length ; i++ ) {
if(board[row][i]!=-1) safe = false;
}
}
}
return safe;
}`所以这个函数得到了女王的位置(假设它是有效的),然后我想检查这一行,直到我的皇后,然后在它之后,看看是否有其他的皇后,如果有,我想检查它们之间是否有墙来保护我的女王,显然我的没有工作,因为如果他们之间除了一堵墙之外,它会产生假的,这就足够了,只有一堵墙,它不一定是所有的墙。
* Q * * X Q' * X Q我用‘表示我的女王,我的代码将返回假的那个例子,即使它应该是真的..然后我必须对对角线和列做同样的操作。这是我需要帮助的地方。
发布于 2018-12-03 09:10:53
这是一个使用Iterator的绝佳机会。
static class Board {
private final int width;
private final int height;
private final int[][] board;
private static final int EMPTY = 0;
private static final int WALL = -1;
private static final int QUEEN = 1;
public Board(int width, int height) {
this.width = width;
this.height = height;
board = new int[height][width];
}
public Board(String[] setup) {
this(setup[0].length(), setup.length);
for (int y = 0; y < setup.length; y++) {
for (int x = 0; x < setup[y].length(); x++) {
switch (setup[y].charAt(x)) {
case '*':
board[y][x] = EMPTY;
break;
case 'X':
board[y][x] = WALL;
break;
case 'Q':
board[y][x] = QUEEN;
break;
}
}
}
}
public Iterator<Integer> walk(int xStart, int yStart, int dx, int dy) {
return new Iterator<Integer>() {
int x = xStart;
int y = yStart;
@Override
public boolean hasNext() {
return x + dx < width && y + dy < height
&& x + dx >= 0 && y + dy >= 0;
}
@Override
public Integer next() {
return board[y += dy][x += dx];
}
};
}
public int get(int x, int y) {
return board[y][x];
}
}
enum Direction {
NORTH(0, -1),
NORTH_WEST(1, -1),
WEST(1, 0),
SOUTH_WEST(1, 1),
SOUTH(0, 1),
SOUTH_EAST(-1, 1),
EAST(-1, 0),
NORTH_EAST(-1, -1),
;
private final int dx;
private final int dy;
Direction(int dx, int dy) {
this.dx = dx;
this.dy = dy;
}
}
public static boolean isQueenThreatened(Board board, int row, int col) {
for (Direction direction : Direction.values()) {
walk: for (Iterator<Integer> attack = board.walk(col, row, direction.dx, direction.dy); attack.hasNext(); ) {
switch (attack.next()) {
case Board.QUEEN:
return true;
case Board.WALL:
break walk;
}
}
}
return false;
}
private void test() {
String[] test = new String[]{
"**QX*Q",
"**X***",
"*QXXQ*",
"Q*XQQ*"
};
Board board = new Board(test);
for (int y = 0; y < board.height; y++) {
for (int x = 0; x < board.width; x++) {
if (board.get(x, y) == Board.QUEEN) {
System.out.println("Queen at position (" + x + "," + y + ") is " + (isQueenThreatened(board, y, x) ? "" : "NOT") + " threatened");
}
}
}
}顺便说一句,您在(0,2) 的女王在(2,4)受到了女王的威胁。
发布于 2018-12-03 08:21:08
对于给定的皇后位置,您需要迭代行、列和每个对角线。在每个方向上,您都可以遵循相同的规则:
true。public static boolean isQueenThreatened(int[][] board, int row, int col) {
// Go over the row, to the left:
for (int i = col - 1; i >= 0; --i) {
int val = board[row][i];
if (val == 1) {
return true;
}
if (val == -1) {
break;
}
}
// Same logic for:
// - Going over the row to the right
// - Going over the column to the top
// - Going over the column to the bottom
// - Going over the top left diagonal
// - Going over the top right diagonal
// - Going over the bottom left diagonal
// - Going over the bottom right diagonal
// If you reached here, it means that no early return was performed,
// and the queen is safe
return false;
}编辑:
为了满足注释中的要求,您可以添加额外的boolean来查找撞墙威胁,但我认为代码看起来要糟糕得多:
public static boolean isQueenThreatened(int[][] board, int row, int col) {
boolean threat = false;
// Go over the row, to the left:
boolean wall = false;
for (int i = col - 1; i >= 0 && !threat && !wall; --i) {
int val = board[row][i];
if (val == 1) {
threat = true;
}
if (val == -1) {
wall = true;
}
}
// Go over the row, to the right.
// Reset the wall variable, as you haven't detected a wall in this direction yet
// The threat potentially found in the previous loop is still present
// so if it still exists, the loop will be skipped
boolean wall = false;
for (int i = col + 1; i < board[row].length && !threat && !wall; ++i) {
int val = board[row][i];
if (val == 1) {
threat = true;
}
if (val == -1) {
wall = true;
}
}
// Same logic for:
// - Going over the column to the top
// - Going over the column to the bottom
// - Going over the top left diagonal
// - Going over the top right diagonal
// - Going over the bottom left diagonal
// - Going over the bottom right diagonal
// If you reached here, it means that no early return was performed,
// and the queen is safe
return threat;
}https://stackoverflow.com/questions/53589529
复制相似问题