码迷,mamicode.com
首页 > 其他好文 > 详细

回溯法(8皇后问题)

时间:2017-10-22 11:01:17      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:end   表示   mes   .com   oid   bool   八皇后   logs   std   

递归函数不再调用它本身,而是返回上一层调用,这种现象称为回溯

表现在解答树中就是一个结点本来应该有的分支因为不满足条件而没有接续产生分支。

 

八皇后问题:在8*8的棋盘上,放置8个皇后,使其不互相攻击,皇后的攻击范围为同行同列和同对角线,找出所有解。

思考可知:每一行只能放一个,每一列也只能放一个。

用c[i]表示第i行的皇后的列数,行数、列数范围都是0~7。

问题变成了0~7的排列问题。枚举数为8!= 40320个,枚举数不会超过它。

又因为位置不同行不同列不同对角线的限制,一些排列不会把整个排列都列出就可以判断不符合情况(这也是递归构造和直接枚举的不同,递归构造可以把生成和检查的过程有机结合起来,而直接枚举必须生成所有可能的解,然后一一检查),表现在解答树中,就是只有满足条件的结点有分支,不满足条件的没有分支而是回溯了。

 

同行同列的判断条件好想,同对角线的条件是:行数差的绝对值等于列数差的绝对值。判断时用当前的行、列数和已经排好的行、列数比较。(祖父结点是排好的/A[0]~A[cur - 1]是排好的)

#include<iostream>
using namespace std;

void f(int A[], int cur, int n)
{
    if(cur == 8)
    {
        for(int i = 0; i < 8 ; i ++)
        {
            cout << A[i] << ,;
        }
        cout << endl;
        return ;
    }
    for(int i = 0; i < n; i++)
    {
        bool flag = true;
        for(int j = 0; j < cur; j ++)
        {
            if(i == A[j])
            {
                flag = false;
                break;
            }
            if(cur - j == i - A[j] || cur - j == A[j] - i)
            {
                flag = false;
                break;
            }
        }
        if(flag)
        {
            A[cur] = i;
            f(A, cur + 1, n);
        }
    }
}

int main()
{
    int A[8];
    f(A, 0, 8);
    return 0;
}

技术分享技术分享技术分享技术分享

 

回溯法(8皇后问题)

标签:end   表示   mes   .com   oid   bool   八皇后   logs   std   

原文地址:http://www.cnblogs.com/mu-ye/p/7707891.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!