8皇后问题总结

//为了巩固总结自己所学的知识,特意写下此博客,如有不当之处希望大神们多多批评
//
//题目分析:
//        使皇后们不在同一列,同一行,同一斜行。
//  用数组mark[]标记 数组的下标来表示行,数组的值是列,
//  那么斜行又分为两种情况,主对角线,cur+mark[cur],副对角线,cur-mark[cur]
//Example 1  //通过行来查找。所以mark[cur]便是列。
#include <iostream>
using namespace std;
const int maxn=10000;
int n,tot = 0,mark[maxn]={0};
void search(int cur) {
    if (cur == n) tot++;
    else {
        for (int i = 0;i < n; i++) {
            int ok = 1;
            mark[cur] = i;//尝试把皇后放在第i列
            for (int j = 0;j < cur; j++) {   //检查是否满足条件
                if (mark[cur]==mark[j]||cur+mark[cur]==j+mark[j]||cur-mark[cur]==j-mark[j]) {
                    ok = 0;
                    break;
                }
            }
            if (ok) search (cur + 1);
        }
    }
}
int main() {
    cin >> n;
    search (0);//从第0个开始
    cout << tot << endl;
}


//Example 2  //用二维数组优化
//该方法用一个二维数组vis[0][maxn]标记列,vis[1][maxn]来标记主对角线,vis[2][maxn]来标记副对角线
// vis[0][i]来检查是否该列有皇后,vis[1][cur+i]检查主对角线,vis[2][cur-i+n]来标记副对角线

#include <iostream>
using namespace std;
const int maxn=10000;
int tot=0;
int n;
int p[maxn];
int vis[3][maxn]={0};
void search (int cur) {
    if (cur == n) tot++;
    else {
        for (int i=0;i<n;i++) {
            if (!vis[0][i] && !vis[1][cur+i] && !vis[2][cur-i+n]) {//这里用cur-i+n 的目的是为了防止cur-i<0
                p[cur]=i;//用p数组来记录放的位置
                vis[0][i] = vis[1][cur+i] = vis[2][cur-i+n] = 1;
                search (cur+1);
                vis[0][i] = vis[1][cur+i] = vis[2][cur-i+n] = 0;
            }
        }
    }
}
int main() {
    cin >> n;
    search (0);
    cout << tot << endl;
}

//第二种之所以比第一种优化,是因为少了一层循环。

 

posted @ 2014-02-08 19:50  闪光阳  阅读(494)  评论(0编辑  收藏  举报