【问题标题】:Why the "if" didn't work ? (n queen problem)为什么“如果”不起作用? (n皇后问题)
【发布时间】:2021-08-25 13:04:44
【问题描述】:

这是我的代码

#include <iostream>
#include <vector>
using namespace std;

int k = 4;
vector<int> QLocation(k,0);
vector<vector<string> > board(k, vector<string>(k, "."));

bool check(int row, int column)
{
    if (row == 0) return true;

    for (int m = row - 1, n = 1; m >= 0; m--, n++)
    {
        if (board[m][column] == "Q") return false;
        if (column + n < n && board[m][column + n] == "Q") return false;
        if (column - n >= 0 && board[m][column - n] == "Q") return false;
    }
    return true;
}

void solve(int row, int column)
{
    for (int i = row; i < k;i++)
    {
        for (int j = column; j < k; j++)
        {
            if (check(i, j))
            {
                board[i][j] = "Q";
                QLocation[i] = j;
                break;
            }
            else
                board[i][j] = ".";

            if (j == k - 1)
            {
                i -= 1;
                j = QLocation[i];
            }
        }
    }
}

int main()
{    
    solve(0, 0);
    for (int i = 0; i < k; i++)
    {
        for (int j = 0; j < k; j++)
            cout << board[i][j];
        cout << endl;
    }
}

输出是无限循环

我在第11、15、16、17、28行设置断点,逐步检查值变化

当i=2,j=1时,输入校验,当m=1,n=1,board[m][column + n] == "Q"但不返回false

为什么?

====== 2021/08/25 22:00 更新======

当我删除这些代码并且 k=4

if (j == k - 1)
{
    i -= 1;
    j = QLocation[i];
}

输出是

Q...
..Q.
.Q..
....

当k=8时输出为

Q.......
..Q.....
.Q......
.....Q..
.......Q
...Q....
........
....Q...

第三行总是失败,但其他行都正确

【问题讨论】:

  • +1 用于调试器。您能否指出问题出在哪一行(例如通过添加代码注释)?
  • 是否应该将if (j == k - 1) 设置为.
  • column + n &lt; n 只有在 column 为负时才为真,但我看不到这种情况会发生。
  • @blackbrandt 在第 16 行 if (column + n
  • 另外,你如何让1 + 1 &lt; 1 为真?

标签: c++ n-queens


【解决方案1】:

编辑:此答案假定您已将 if(column + n &lt; n ...) 中的错字更正为 if(column + n &lt; k ...)

问题出在这部分

if(j == k-1){
   i -= 1;
   j = Qlocation[i];
}

考虑迭代中 k = 4 和 i = 2 的情况。届时,董事会将看起来像这样。

Q...
..Q.
....
....

这里check(i, j) 对于 i = 2 始终为假,所以 i 回到 1。但你没有将 board[i][Qlocation[i]] 的值改回 '.'。这是一个错误(即使你纠正了这个,它也不起作用。我会告诉你为什么假设你通过在 j = Qlocation[i]; 之后添加 board[i][j] = "." 来纠正它)。现在值是 i = 1,j = 3(for 循环中的 j++)。检查返回真,你在那里放置一个皇后,i 增加到 2。

董事会:

Q...
...Q
....
....

这里,对于 j = 1,check(i, j) 返回 true。棋盘:

Q...
...Q
.Q..
....

现在 i = 3。check(i, j) 对所有 j 都失败。 i 减少到 2,j 减少到 2(j = Qlocation(i), j++)。 check(i, j) 对 (2, 2) 和 (2, 3) 失败,此时 i 进一步减少到 1,j 减少到 4 (j = Qlocation(1), j++)。

董事会:

Q...
....
....
....
because of board[i][j] = ".";

现在 j = 4 不满足条件 j i 增加到 2。 check(i, j) 返回 true for j = 1 . 董事会:

Q...
....
.Q..
....

现在 i = 3,check(i, j) 对所有 j 都失败,i 变为 2。 check(i, j) 对 j = 3 返回 true。棋盘:

Q...
....
...Q
....

现在再次 i = 3,check(i, j) 为 j = 1 返回 true。最终答案:

Q...
....
...Q
.Q..

这是错误的。因此,您必须添加检查 for 循环是否在行中没有任何 Q 的情况下退出。

【讨论】:

  • 你是对的,我添加了 board[i][j] = "."在 j = QLocation[i] 之后;但我仍在尝试解决问题
【解决方案2】:

我认为你的问题在这个逻辑中。

for (int m = row - 1, n = 1; m >= 0; m--, n++)

您正在检查 m 何时等于或大于 0。但您从 -1 开始,每次迭代都减去 1。这意味着除非返回,否则您将永远不会停止。

我猜mboard[m][column] 没有board[-10][5],它可能有board[10][5]。 Sou 你永远不会返回 false。

【讨论】:

  • row == 0 提前返回,所以这可能不是正在发生的事情。
【解决方案3】:

上帝……我的眼睛坏了。虽然查了很多遍,还是没找到第16行

if (column + n <n && board[m][column + n] == "Q") return false;

column + n &lt; n 应改为column + n &lt; k

感谢molbdnilo,很抱歉浪费大家的时间

====== 2021/08/26 00:05 更新======

我终于修好了,这是代码

(我知道它很丑,有例外(比如k=3)和多种解决方案(比如k=4有两种解决方案)要处理)

#include <iostream>
#include <vector>
using namespace std;

int k = 4;
vector<int> QLocation(k,0);
vector<vector<string> > board(k, vector<string>(k, "."));

bool check(int row, int column)
{
    if (row == 0) return true;

    for (int m = row - 1, n = 1; m >= 0; m--, n++)
    {
        if (board[m][column] == "Q") return false;
        if (column + n < k && board[m][column + n] == "Q") return false;
        if (column - n >= 0 && board[m][column - n] == "Q") return false;
    }
    return true;
}

void solve(int row, int column)
{
    bool rowFail = false;

    for (int i = row; i < k; i++)
    {
        for (int j = column; j < k; j++)
        {
            if (check(i, j))
            {
                board[i][j] = "Q";
                QLocation[i] = j;
                rowFail = false;
                break;
            }
            else
            {
                board[i][j] = ".";
                rowFail = true;
            }
        }

        if (rowFail)
        {
            column = QLocation[i -= 1];
            board[i][column] = ".";
            i -= 1;
            column += 1;
        }
        else
            column = 0;
    }
}

int main()
{    
    solve(0, 0);
    for (int x = 0; x < k; x++)
    {
        for (int y = 0; y < k; y++)
            cout << board[x][y];
        cout << endl;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-02
    • 2021-06-02
    • 2020-06-22
    • 1970-01-01
    • 1970-01-01
    • 2020-07-19
    • 2020-07-04
    • 1970-01-01
    相关资源
    最近更新 更多