【问题标题】:5 queens on a 8x8 chess board8x8 棋盘上有 5 个皇后
【发布时间】:2014-07-08 18:31:10
【问题描述】:

我正在尝试找出在棋盘上设置 5 个皇后而不让它们互相攻击的可能方法的数量。我已经成功找到了第一组。问题是我如何才能找到 5 个皇后的下一组位置。我的程序中的程序是这样的:

  • 根据棋盘上的当前皇后生成一个包含不允许位置的向量
  • 遍历板上的所有位置
  • 检查当前位置是否是板上不允许的位置之一
  • 如果不是,则返回位置,将其添加到棋盘上的皇后向量中,然后重新开始该过程

继续直到没有更多位置可用,即所有剩余位置都不允许

#include <iostream>
#include <vector>

using namespace std;
const int BSIZE = 8;
char chessBoard[BSIZE][BSIZE];

struct qPos
{
    qPos() : h(0), v(0), found(true) {}
    int h; //horizontal pos
    int v; //vertical pos
    bool found; //if position is available
};

qPos findNextQPos(vector<qPos> Qs);
void fillBoard(vector<qPos> Qs);
void print();
vector<qPos> generateDisallowed(vector<qPos> Qs);
bool isDisallowed(qPos nextPos, vector<qPos> disallowedPos);

int main(int argc, char **argv){
    vector<qPos> QsOnBoard; //Position of all the queens on board
    qPos nextQ; //next possible position
    while (nextQ.found)
    {
        nextQ = findNextQPos(QsOnBoard);
        if (nextQ.found)
        {
            QsOnBoard.push_back(nextQ); //If the nextQ is available i.e. not disallowed, add it to the queens vector
        }
    }
    fillBoard(QsOnBoard); //Fill the board with queens positions
    print(); // print the board
    return 0;
}

qPos findNextQPos(vector<qPos> Qs) {
    // Generate disallowed positions based on all the queens on board
    vector <qPos> disallowedPos = generateDisallowed(Qs);
    qPos nextQ;
    for (size_t i = 0; i < BSIZE; i++)
    {
        for (size_t j = 0; j < BSIZE; j++)
        {
            nextQ.h = i;
            nextQ.v = j;
            if (!isDisallowed(nextQ, disallowedPos)) { //Check if next possible position is a disallowed position
                //cout << "Next available:\n" << nextQ.h << ", " << nextQ.v << endl;
                return nextQ; // if it is avaible return the position, break the loop
            }
        }
    }
    nextQ.found = false; // No available position is found to return, found is set to false, return the position
    return nextQ;
}

我拥有其他功能(例如生成禁止和 isDisallowed 等)的其余源代码位于 this pastebin。我认为它与问题无关,这里的代码不应该太长。

第一组的结果如下所示: 那么我应该如何继续才能找到所有解决方案集?这就是我卡住的地方。

【问题讨论】:

  • 您是否需要使用代码,或者组合解决方案就足够了?
  • @abiessu 我更喜欢使用代码。使用组合解决方案,我什至不需要走到这一步,对吧?我想可以根据棋盘的大小和皇后的数量来计算。
  • 为什么我会否决这个问题?谁能给我解释一下?
  • 不确定否决票,您似乎自己做了一些工作以尝试解决方案,并且您似乎试图自己理解问题空间。我建议使用组合路线,因为通过每个解决方案几乎肯定会产生许多重复的皇后阵型,包括在棋盘空间中的旋转和翻转和平移。
  • @abiessu 是的,我知道旋转和翻转会有很多解决方案,但我实际上正在寻找独特的解决方案。但是出于好奇,您能告诉我组合解决方案吗?谢谢

标签: c++ algorithm


【解决方案1】:

首先,将这两个循环合二为一:

for (size_t i = 0; i < BSIZE; i++)
{
    for (size_t j = 0; j < BSIZE; j++)
    {

改为:

for (size_t n = 0; n < (BSIZE * BSIZE); ++n)
{
    size_t i = n % BSIZE;
    size_t j = n / BSIZE;

现在您的函数可以很容易地从n 开始。要找到“下一个”解决方案,只需删除最后一个皇后(注意它的位置)并调用FindNextQPos,告诉它从那个皇后过去的位置开始。如果该皇后已经在最后一个位置,则返回并移除另一个皇后。

如果您没有找到解决方案,请执行与找到解决方案相同的操作。移除最后一个皇后并调用FindNextQPos,再次从您移除的皇后位置开始。

当你没有皇后要移除时,你就完成了。

您可以使用单个“继续”功能来完成此操作。无论您找到解决方案还是未找到解决方案,您都可以调用此函数。它的逻辑是:

  1. 找到最后一个皇后。如果没有最后一个女王,就停下来。我们完成了。

  2. 注意它的位置。删除它。

  3. 呼叫FindNextQPos,从我们记录的位置的后一位置开始。如果我们放置了一个皇后,请继续尝试从零位置开始放置更多的皇后,直到我们找到解决方案或无法放置一个皇后。

  4. 如果我们找到了解决方案,输出它。

  5. 转到步骤 1。

【讨论】:

  • 听起来可以!只是阅读对我来说有点难以理解,但我尝试了一下。所以基本上我们正在做的就是让最后一个女王总是向前移动,直到我们到达终点。然后移动另一个女王,对吧?走到最后的女王怎么办?
  • 当一个皇后走到尽头时,您将其删除。然后你重复,再次移除最后一个皇后并试图推进它。 (要理解该算法,可能值得在头脑中考虑您只是尝试将五块任何地方放在板上的情况。然后您只需要数数,这正是该算法的内容算的时候,怎么从19到20?9之后没有下一位,所以你去掉最后一位,增加第一位,然后尝试从零开始放一个新的最后一位。)
  • 如果我在这里听起来像个白痴,我很抱歉,但是如果我删除棋盘上的皇后,那么剩下 4 个皇后,不再是 5 个。这开辟了许多设置它们的新方法。
  • @Erfan 我不确定我是否关注你。您必须首先将一个皇后放在一个空板上。然后你必须将第二个皇后放在一个已经在上面的棋盘上。 (它可以帮助您完成一个简单的示例,例如输出每个三位数字。首先放置第一位,然后是第二位,然后是第三位,然后输出解决方案。然后删除第三位并尝试在它的位置放一个更大的。等等。)
猜你喜欢
  • 2020-01-10
  • 1970-01-01
  • 2017-05-31
  • 2020-12-12
  • 1970-01-01
  • 2015-05-23
  • 1970-01-01
  • 2017-05-27
  • 1970-01-01
相关资源
最近更新 更多