我最近刚刚开始在CS环境中学习简单递归功能,以及组合应用程序以及诸如Backtracking and Divide ET Impera之类的技术。

我为我的问题选择的示例问题是n皇后问题(给定皇后区和*n棋盘,您如何将皇后定位,以免彼此攻击?)。我知道,基本思想是生成所有可能的位置(通过生成笛卡尔产品),然后在它们无效(通过验证功能)时简单地丢弃它们。

这是我的示例实现:

    int valid (int k)
    {
    for (int i = 1; i < k; i++)
    {
        if (sol[i] == sol[k]) return 0;
        if (abs(sol[i] - sol[k]) == abs(i - k)) return 0;
    }
    return 1;
}

void print ()
{
    for (int i = 1; i <= n; i++)
    {
        cout << sol[i];
    }
    cout << endl;
    how++;
}

void backtrack (int k)
{
    if (k == n+1) print();
    else
    {
        sol[k] = 0;
        while (sol[k] < n)
        {
            sol[k]++;
            if (valid(k)) backtrack(k+1);
        }
    }
}
  1. 为什么在验证函数中,通过用k,2用K等检查1逐渐检查解决方案的检查。我认为该解决方案可以成对正确,但总体上是错误的(例如,相对于3个相对于3个相对于2的第1和2个相对于2个相对于2个相对于2的放置)吗?
有帮助吗?

解决方案

例如,相对于3相对于3的1和2正确放置,但相对于2的1相对于2的放置错误地放置了错误吗?

您已经测试了1和2正确放置,否则您不会打电话 backtrack(3).

回顾 sol[i] = j 意味着$ i $中的女王将其放在行$ j $上。通过打电话 backtrack(k+1) 您已经验证了$ 1 dots k $中的每个女王都正确放置(非填料)。

许可以下: CC-BY-SA归因
不隶属于 cs.stackexchange
scroll top