【问题标题】:All Possible Combinations in Grid网格中所有可能的组合
【发布时间】:2014-05-16 04:04:47
【问题描述】:

好的,所以这一直困扰着我一段时间,我有点碰壁了。假设您有一个表示为二维数组的方形网格,并且每个单元格都可以处于两种状态之一。您将如何构建一个可能存在于所述网格中的每个可能组合的列表?我意识到这对于较大的网格是不切实际的,但对于像 5x5 或更小的网格,我想可以简单地枚举每个可能的组合。

另外,我正在尝试解决 nurikabe 难题并找到所有可能的配置。我还有很多其他的东西要修剪,但是构建可能配置的原始列表让我很头疼

【问题讨论】:

  • 5 x 5 的所有组合将为您提供 5*5*2*5 的总组合数。您打算将每个配置保存在另一个阵列中吗?跨度>
  • @durbnpoisn 这将给出 2^(5*5) 个组合,大约是 3300 万。

标签: algorithm math c++11 combinations


【解决方案1】:

对于一个 5x5 的正方形,有 2^25 种可能的组合。

因此您可以使用 32 位整数来表示一个。


这是一个将整数转换为正方形的函数:

void Id2Square(const unsigned int& id,bool square[SIZE][SIZE])
{
    for (int n=0; n<SIZE*SIZE; n++)
        square[n/SIZE][n%SIZE] = (bool)((id>>n)&1);
}

这是一个将平方转换为整数的函数:

void Square2Id(unsigned int& id,const bool square[SIZE][SIZE])
{
    id = 0;
    for (int n=0; n<SIZE*SIZE; n++)
        id |= (unsigned int)square[n/SIZE][n%SIZE]<<n;
}

因此,例如,如果您想检查所有可能的正方形,则可以按以下方式进行:

void CheckAllSquares()
{
    bool square[SIZE][SIZE];
    for (int id=0; id < 1<<(SIZE*SIZE); id++)
    {
        Id2Square(id,square);
        // Now do whatever you want to do with 'square'
    }
}

【讨论】:

    【解决方案2】:

    您可以将其视为简单的 n*n 二进制数,其中 n 是正方形网格的边的大小。此时,您所要做的就是以二进制从 000...0(n 个零)计数到 111...1(n 个一)并保存每个数字。然后,如果需要,您可以通过运行二进制数并将其转换为数组格式,并在每 n 位数后转到数组中的下一行。

    【讨论】:

    • 天啊。这正是我要建议的,但想不出如何解释。 “把它想象成一个自行车锁,有五个转动的轮子,只能是 1 或 0。”和我来的时候一样近。
    猜你喜欢
    • 1970-01-01
    • 2012-03-27
    • 1970-01-01
    • 2018-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多