我正在尝试编写一个功能,该功能获得MxN尺寸的板子,并在其中放置一列和一列,其中放置一个女王。然后我想看看那个女王是否受到威胁。 通常,我会将该行并检查是否有其他皇后区,对于列和对角线也使用for循环进行检查。 但是这里稍有变化,即使在同一行中还有另外一堵墙,木板上的墙壁也可以使皇后区安全:
* * Q X * Q
* * X * * *
* Q X X Q *
Q * X Q Q *
其中Q是皇后,X是墙,*是空瓷砖。 即使排在第二位的女王也不会受到威胁。
整个板子也保存在一个2d数组中,其中为Queens赋予int值为1,墙为-1,空白为0。
我的想法是遍历整行,如果某个地方有皇后,那么我应该寻找一堵墙,从该位置一直到我要看的皇后,再铺一层for环。但是在我的女王之后还有第二部分。
我尝试过考虑求和,但这也不是很有效。 有人对如何实现这一点有任何想法吗? (如果受到威胁,则返回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
我用'标记了我的女王,即使该示例为true,我的代码也将返回false。然后,我必须对角线和列做同样的操作。帮助。
答案 0 :(得分:1)
这是与Iterator
s合作的绝佳机会。
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)
受到女王的威胁。
答案 1 :(得分:0)
对于给定的皇后位置,您需要遍历行,列和每个对角线。在每个方向上,您都可以遵循相同的规则:
var result = data2.GroupBy(n => new { n.Name, n.Date})
.Select(cl => new Result
{
Name = cl.First().Name,
Date = cl.First().Date,
Hours = cl.Sum(c => c.Hour),
}).ToList();
。
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;
}
来发现撞墙的威胁,但是TBH,我认为代码看起来会更糟:
boolean