检查2D网格的元素是否与另一个元素共享对角线,水平线或垂直线

时间:2018-10-14 23:56:52

标签: c++ arrays vector traversal

我正在研究n皇后问题,其中一部分是检查皇后是否受到另一人的威胁来确定一个好的棋盘状态。

我有一个用0填充的2D数组,在这个例子中是4x4:

0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

我在每一行中随机填充一个皇后,在本例中以1:

表示
0 0 1 0
1 0 0 0 
1 0 0 0
0 0 0 1

我需要检查还有多少其他东西威胁给定的一块。如果女王/王后与另一个女王/王后在水平,对角或垂直方向上共享,则会受到威胁。

但是,我不确定如何对角遍历数组。

int checkThreats(vector<vector<int> > board, int r, int c) {
    int threats = 0;
    // checks vertical and horizontal
    for (int i = 0; i < board.size(); i++) {
        if (board[i][c] == 1 || board[r][i] == 1) {
            threats++;
        }
    }
    // it will count itself as a threat, so less one
    threats--;
    return threats;
}

这是用于水平和垂直检查的算法。给定在板上r, c上的位置后,它将检查在左侧,右侧,上侧和下侧(十字+形状)位置中存在多少个皇后。

采用r, c的坐标1, 0,检查的位置标记为x,如果存在威胁,则标记为o

x 0 1 0
o x x x
o 0 0 0
x 0 0 1

在这种情况下,threats == 1,因为我们不计算原始位置。

我的问题是试图沿着对角线找到x形的碎片。

2 个答案:

答案 0 :(得分:1)

使用对角线的技巧是它们具有不同的长度(总计和分别;考虑到它们仅从板的边缘或角开始包括3个正方形,而从中间开始仅5个正方形)。这种不规则性使他们难以解释。

一种策略是遍历(说)这些行,并分别考虑该行对角线上的0(如果是主题行),1(如果一个不在画板上)或2个正方形。要检查的列索引仅为c0+(r-r0)c0-(r-r0)

答案 1 :(得分:0)

通过反复试验,我能够使算法起作用。这是遍历所有方向的循环:

function check(arr, row, col) {
    for (i = 0; i < arr.size(); i++) {} // left/right can be iterated as normal
    for (i = 0; i < arr.size(); i++) {} // top/down can be the same
    // lower-right diagonal from (row, col)
    for (i = row+1, j = col+1; i < arr.size() && i < arr.size(); i++, j++) {}
    // upper-left diagonal from (row, col)
    for (i = row-1, j = col-1; i >= 0 && j >= 0; i--, j--) {}
    // lower-left diagonal from (row, col)
    for (i = row-1, j = col+1; i >= 0 && j < arr.size(); i--, j++) {}
    // upper-right diagonal from (row, col)
    for (i = row+1, j = col-1; i < arr.size() && j >= 0; i++, j--) {}
}

这当然仅适用于正方形阵列。