n 皇后问题的递归和回溯实现 C++

来源:互联网 发布:fm2016怎么选择数据库 编辑:程序博客网 时间:2024/05/04 09:55
/** *n皇后问题 * */#include <iostream>using namespace std;bool IsLegal (int *c, int n){//位图标志数组,使用 1 ~ n位,最大表示为1 ~ 31,即int型占32位。//若要求 n > 31 皇后问题,则需修改位图标志数组。unsigned int bitmap = 1;//检查全部皇后是否在同一列,若是,则非法。for (int i = 1; i <= n; ++i){if ((bitmap >> c[i]) & 1) return false;elsebitmap |= 1 << c[i];}//检查两两皇后间是否存在在同一对角线上的情况,若是,则非法。for (int i = 1; i < n; ++i)for (int j = i + 1; j <= n; ++j)if (c[i] - c[j] == i - j || c[i] - c[j] == j - i)return false;//反之,合法。return true;}void printArray (int *c, int n){for (int i = 1; i <= n; ++i)cout << c[i] << " ";cout << endl;}//记录解法的数目static int cnt = 0;void Queens_Recursion (int *c,int n,int k){for (int i = 1; i <= n; ++i){c[k] = i;//为解答树的第K层生成节点if (IsLegal(c,n)){//是最终解,则输出结果printArray(c,n);cnt ++;}else if (IsLegal(c,k)) //是部分解,则继续穷举Queens_Recursion(c, n, k + 1); //进入k+1层}}void Queens_iteration (int *c,int n){int k = 1;//解答树从第一层开始while (k >= 1){while (c[k] < n ){c[k]++;//为解答树的第K层生成节点if (IsLegal(c, n)){//是最终解,输出结果cnt ++;printArray(c, n);break;}else if (IsLegal(c,k)) //是部分解,进入k + 1层k ++;}//回溯c[k] = 0;k --;}}int main(){const int N = 4;//N 表示n  皇后    int c[20] = {0};    for (int i = 1; i <= N; ++i)c[i] = 0;//Queens_iteration(c, N);Queens_Recursion(c, N, 1);    cout << "Total : " << cnt;    return 0;}