八皇后问题(回溯)

 

时限:1000ms 内存限制:10000K  总时限:3000ms

描述

输出8皇后问题所有结果。

输入

没有输入。

输出

每个结果第一行是No n:的形式,n表示输出的是第几个结果;下面8行,每行8个字符,‘A’表示皇后,‘.’表示空格。不同的结果中,先输出第一个皇后位置靠前的结果;第一个皇后位置相同,先输出第二个皇后位置靠前的结果;依次类推。

输入样例

 

输出样例

输出的前几行:
No 1:
A…….
….A…
…….A
…..A..
..A…..
……A.
.A……
…A….
No 2:
A…….
…..A..
…….A
..A…..
……A.
…A….
.A……
….A…

程序如下:

#include <iostream>
#include <cstdlib>

using namespace std;
int a[8]={0};
int sum=0;
void print()
{
    int i,j;
    cout<<"No "<<sum<<":"<<endl;
    for(i=0;i<8;i++)
    {
        for(j=0;j<8;j++)
            {
                if(a[i]==j)
                    cout<<'A';
                else
                    cout<<'.';
            }

        cout<<endl;
    }
}
int canplace(int row,int col)
{
    int i;
    for(i=0;i<row;i++)
    {
      if(a[i]==col||abs(i-row)==abs(a[i]-col)) 
                return 0;

    }
   return 1;
}
void search(int m)
{
    if(m==8)
    {
        sum++;
        print();
    }

    else
    {   int i;
        for(i=0;i<8;i++)
        {
            a[m]=i;
            if(canplace(m,i))
            {
                search(m+1);
            }
        }
    }
}
int main()
{
    search(0);

    return 0;
}
void search(int m)
{
    if(m==8)
    {
        sum++;
        print();
    }

    else
    {   int i;
        for(i=0;i<8;i++)
        {
            a[m]=i;
            if(canplace(m,i))
            {
                search(m+1);
            }
        }
    }
}

       算法是逐行安排皇后的,其参数m为现在正执行到第几行。8是皇后数.

  第2行好理解,如果程序当前能正常执行到第8行,那自然是找到了一种解法,于是八皇后问题解法数加1。

  如果当前还没排到第八行,则进入else语句。遍历所有列col,将当前col存储在数组a里,然后使用canplace()检查row行col列能不能摆皇后,若能摆皇后,则递归调用search去安排下一列摆皇后的问题。

  还不太清楚?再慢点来,刚开始的时候row=0,意思是要对第0行摆皇后了。

  If判断失败,进入else,进入for循环,col初始化为0

  显然,0行0列的位置一定可以摆皇后的,因为这是第一个皇后啊,后宫空荡她想怎么折腾就怎么折腾,于是canplace(0,0)测试成功,递归调用search(1)安排第1行的皇后问题。

  第1行时row=1,进来if依然测试失败,进入for循环,col初始化为0。1行0列显然是不能摆皇后的,因为0行0列已经有一个圣母皇太后在那搁着了,于是canplace()测试失败,循环什么也不做空转一圈,col变为1。1行1列依然canplace()测试失败,一直到1行2列,发现可以摆皇后,于是继续递归search(2)去安排第二个皇后位置。

  如果在某种情况下问题无解呢?例如前面在4皇后问题中,0行0列摆皇后是无解的。假设前面递归到search(2)时候,发现第2行没有地方可以摆皇后,那怎么办呢?要注意search(2)的调用是在search(1)的for循环框架内的,search(2)若无解,则自然而然search(1)的for循环col自加1,即将第1行的皇后从1行2列改为1行3列的位置,检查可否放皇后后继续安排下一行的皇后。如此递归,当search(0)的col自加到7,说明第一列的皇后已经遍历了从0行1列到0行7列,此时for循环结束,程序退出。

  在主函数中调用search(0),得到正确结果,8皇后问题一共有92种解法。

    原文作者:八皇后问题
    原文地址: https://blog.csdn.net/zhao2018/article/details/82847228
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞