回溯法解决n皇后问题

回溯法解决n皇后问题

代码如下:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define N 20                               //最多皇后个数

using namespace std;
int q[N];                                  //存放各皇后所在的列号,为全局变量
int num = 0;                               //累计解个数


void dispasolution(int n) {                  //输出一个解
	cout << "第" << ++num << "个解:" << endl;
	for (int i = 1; i <= n;i++) {
		cout << "(" << i<<","<<q[i] << ")" ;
	}
	cout << endl;
}


bool place(int i) {                          //测试第i行的q[i]列上能否摆放皇后

	int j = 1;
	if (i==1) {
		return true;
	}
	while (j<i) {
		if ((q[j]==q[i])||(abs(q[j]-q[i])==abs(j-i))) { //该皇后是否与以前的皇后同列,位置(j,q[i])是否同对角线
			return false;                                 
		}
		j++;
	}
	return true;
}


void queens(int n) {                         //求解n皇后问题
	int i = 1;                               //i表示当前行,也表示放置第i个皇后
	q[i] = 0;                                //q[i]是当前列,每个新考虑的皇后的初始位置置为0列
	while (i>=1) {                           //尚未回溯到头,循环
		q[i]++;                              //原位置后移一列
		while (q[i]<=n&&!place(i)) {         //试探一个位置(i,q[i])
			q[i]++;
		}
		if (q[i]<=n) {                       //为第i个皇后找到了一个合适位置(i,q[i])
			if (i==n) {                      //若放置了所有皇后,输出一个解
				dispasolution(n);            
			}
			else {                           //皇后没有放置完
				i++;                         //转向下一行,即开始下一个新皇后的放置
				q[i] = 0;                    //每个新考虑的皇后的初始位置为0列
			}

		}
		else {
			i--;                             //若第i个皇后找不到合适的位置,则回溯到上一个皇后
		}
	}
}


int main() {
	int n=0;                                     //n存放实际的皇后个数
	cout << "请输入n" << endl;
	cin >> n;
	cout << n<<"皇后问题求解如下:" << endl;
	queens(n);

	system("pause");
	return 0;
}

【算法分析】该算法中的每个皇后都要试探n列,共n个皇后,其解空间是一棵子集树,不同于前面一般的二叉树子集树,这里每个结点可有n棵子树。对应的算法时间复杂度为O(n^{n})。

 

  • 5
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值