【问题标题】:Checking 2-dimensional array (like eight queens puzzle)检查二维数组(如八皇后拼图)
【发布时间】:2010-09-27 22:41:05
【问题描述】:

我的问题与八皇后谜题非常相似。

例如,我有一个二维数组 (N x N),如下所示:

0,0,0,0,1 y
0,0,0,0,0 |
0,0,0,0,0 V
0,0,0,1,0
0,0,0,0,0
x->

我正在水平、垂直和对角线检查 1 的出现

\,0,|,0,/
0,\,|,/,0
-,-,1,-,-
0,/,|,\,0
/,0,|,0,\

我正在考虑仅将“1”的 (x,y) 位置存储在列表中

[[4,0],[3,3]]

并以数学方式求解,用另一个 (x1,y1)(x2,y2) 检查“1”的每个位置,

如果x1 == x2y1 == y2 we have a collision! 如果不检查:

x2 == x1 + z;
y2 == y1 + z;
x2 == x1 - z;
y2 == y1 - z;

(???)

其中 z 是 +/- 即 ( x1+z in 0..N ) and ( y1+z in 0..N ) .......

我的问题是检查对角线碰撞,有没有更好的方法?

【问题讨论】:

标签: python arrays puzzle


【解决方案1】:

假设你确实有一个 N 维空间,而你可能没有,你可以使用这个碰撞检测器:

def collision(t1, t2):
    return len(set([abs(a-b) for a,b in zip(t1, t2)] + [0])) <= 2

将一对元组传递给你喜欢的任意数量的元组,如果这两个点位于任何 N 维对角线上,它将返回 true。

【讨论】:

    【解决方案2】:

    我认为,如果您不进行数学求解,但首先检查所有行是否多次出现 1,然后检查所有列,最后检查所有对角线,会更快。

    这是一些以简单方式测试对角线的代码。 (这是 JavaScript,抱歉!)

    var count = 0;
    for (column = -n; column < n; column++) {
        for (row = 0; row < n; row++) {
                // conditions for which there are no valid coordinates.
                if (column + row > 6) {
                    break;
                }
                if (column < 0) {
                    continue;
    
                if (field[row][column] == 1) {
                    count++;
                    if (count == 2)
                        break; // collision
                }
        }
    }
    

    此方法的复杂度为O(n^2),而您建议的方法的复杂度为O(n^2 + k^2)(k 是1 的数量)如果k 总是很小,这应该没问题。

    【讨论】:

    • "我的问题是检查对角线碰撞,有没有更好的方法??" ——他并没有试图解决八皇后问题。他只是在检查碰撞。 @dF 的方法是 O(1)。
    • 我的理解是,他检查是否至少有一次碰撞,而不是点 (x,y) 是否有碰撞。 dF 的方法是 O(1),但前提是您假设比较次数是静态的。
    • 不是k = N吗?所以 O(n^2+k^2) = O(2n^2) = O(n^2)?当然,在 8 皇后问题中,k = N。
    • 不,k 是数组中有 1 的位置的数量,n 是数组一侧的长度。
    【解决方案3】:

    您的描述听起来像是一个精确覆盖问题的实例,可以使用 Knuth 调用 Algorithm X 的算法来解决。我已经使用这种技术实现了Sudoku solver in Javascript。你也可以在 Python 中找到实现。

    【讨论】:

    • +1 。这就是我首先想到的。但不确定它,也没有做任何事情,所以等待一个知识渊博的人给他投票。现在找到他了:p
    • 使用碰撞函数做了一个简单的蛮力检查。现在,检查你的方法(虽然看起来很复杂)......谢谢!
    【解决方案4】:

    一种可能的解决方案:

    def collision(x1, y1, x2, y2):
        return x1 == x2 or y1 == y2 or abs(x1-x2) == abs(y1-y2)
    

    即如果两个点在同一水平行、同一垂直行或同一对角线(垂直距离 == 水平距离)上,则会发生碰撞。

    【讨论】:

    • 我希望我能投票。这是一个非常好的答案!但是,您不想找到 abs(dx) 和 abs(dy) 吗?
    • 感谢您提供非常好的答案!我没想到会这么简单;)愚蠢的我...我已经设法使用您的碰撞功能编写了一个简单的蛮力检查器。现在我期待着检查另一个答案中提到的算法 X。
    • y = mx + c 和对角线m = 1。我想知道为什么我的大脑在看到这样的解决方案之前无法工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-02
    相关资源
    最近更新 更多