赞
踩
问题描述:在nxn的棋盘上,放置彼此不受攻击的n个皇后。
规则:皇后可以攻击与之在同一行,同一列,同一斜线上的棋子。
以行为主导(不用再判断是否同行了)
算法设计:
(1)定义问题的解空间:问题解的形式为n元组:
分量xi表示第i个皇后放置在第i行,第xi列。
(2)解空间的组织结构:m叉树
(3)搜索解空间:
约束条件:
,不同列。
,不同斜线。
限界条件:不存在放置方案好坏的问题。
搜索过程:从根开始,以深度优先搜索的方式进行搜索。根结点是活结点,并且是当前的扩展结点。
- #include <iostream>
- #include <cmath>
-
- #define M 105
- using namespace std;
-
- int n;
- int x[M];
- int countn;
-
- bool Place(int t) {
- bool ok = true;
- for (int j = 1; j < t; j++) {
- if (x[t] == x[j] || t - j == fabs(x[t] - x[j])) {
- ok = false;
- break;
- }
- }
- return ok;
- }
-
- void Backtrack(int t) {
- if (t > n) {
- countn++;
- for (int i = 1; i <= n; i++)
- cout << x[i] << " ";
- cout << endl;
- cout << "----------" << endl;
- } else
- for (int i = 1; i <= n; i++) {
- x[t] = i;
- if (Place(t))
- Backtrack(t + 1);
- }
- }
-
- int main() {
- cout << "请输入皇后的个数n: ";
- cin >> n;
- countn = 0;
- Backtrack(1);
- cout << "答案的个数是: " << countn << endl;
- return 0;
- }
算法复杂度分析:
(1)时间复杂度:
除最后一层:个结点需要扩展。
每个结点需要扩展n个分支:
每分支都要判断约束:
叶子个数,每个叶子输出最优解:
因此,时间复杂度为:
(2)空间复杂度:
x[]记录可行解,因此为:O(n)
算法优化扩展:
问题:解空间过大。
原因:使用了不同行作为显约束,使用了不同列,不同斜线作为隐约束。
改进:使用不同行,不同列作为显约束,使用不同斜线作为隐约束,缩小解空间。此时解空间树变为排列树。
例如:
x1=1,则x2不能等于1
x1=1,x2=2,则x3不能等于1,2
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。