首页 > 其他 > 详细

52.N-Queens II

时间:2015-12-19 20:27:09      阅读:516      评论:0      收藏:0      [点我收藏+]

Follow up for N-Queens problem.

Now, instead outputting board configurations, return the total number of distinct solutions.

技术分享


解题思路:回溯法。可以用一个大小为n的一维数组来表示皇后的摆放情况。a[i]=j表示第i行的皇后的摆放位置是第j列。我们假设前面k-1个皇后的摆放位置没有问题,我们如何判断第k个皇后的摆放位置是否有问题呢?相关的判断定义在函数place中,如果i1k-1,都没有a[i]==a[k]||abs(a[i]-a[k])==abs(i-k)成立,那表示第k个皇后的位置摆放的也没有问题。a[i]==a[k]表示两个皇后摆放在同一列,很显然不成立。怎么判断两个皇后摆放在同一条对角线上呢?先来个图示例一下:

技术分享

如果两个皇后在同一条对角线上那么一定有abs(a[i]-a[k])==abs(i-k)成立,可以理解成两者在一个正方形的两个角上。

回溯法的思路是这样的,首先设k=1,每一次循环都是设置第k个皇后摆放的位置。当a[k]<=n&&!place(k)满足时,增加a[k],直至不满足条件退出内部循环,此时第k个皇后要不已经摆放到位,要不a[k]已经超过了n,不满足条件。进一步的,如果k=n,表示第n个皇后摆放到位,相应的又多了一种摆放情况。如果k<n,还要继续处理下一行皇后的摆放,k++。其他情况对应我们不满足要求的情况,此时我们应该回溯,对第k行的皇后摆放设置清空,k--,重新处理第k-1行皇后的摆放。

class Solution {
private:
    int *a;
    int sum;
    bool place(int k){
        int i;
        for(i=1;i<k;i++){
            if(a[i]==a[k]||abs(a[i]-a[k])==abs(i-k))
                return false;
        }
        return true;
    }
public:
    int totalNQueens(int n) {
        int sum=0;
        a=new int [n+1];
        memset(a,0,(n+1)*sizeof(int));
        int k=1;
        while(k>0){
            a[k]++;//第k行开始放在第一纵列
            while(a[k]<=n&&!place(k))//a[k]放在第1到n行,且要保证摆放不破坏规则
                a[k]++;
            if(a[k]<=n&&k==n){//最后的结果满足要求
                sum++;
            }
            else if(a[k]<=n&&k<n)//继续摆放下一行
                k++;
            else //不符合要求,回溯
                a[k--]=0;
                 
        }
        return sum;
    }
};





52.N-Queens II

原文:http://www.cnblogs.com/zhoudayang/p/5059654.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!