算法内功修炼——全排列与实现八皇后(一)

内容:

  1. 全排列实现
  2. 结合全排列实现八皇后
  3. 全排列实现八皇后回溯法优化
  4. 八皇后中对角线判断问题

1、全排列实现

输出一个1~n的全排列。如:1到3,123,132,213,231,312,321

算法描述:

  • 设置一个数组p[maxn],用来存放全排列数字;
  • 设置一个数组hashTable[maxn]用来标记元素是否已经被存入p[]中,类型为bool,返回值为true和false;
  • 第一重循环,枚举1到n,当元素没被标记,即未被存入数组p中,执行下一步;
  • 将元素存入p数组中,即p[index]=i;变量index代表插入位置,此时,外层循环1~n已将1~n存入p[1](index=1);
  • 此时元素i需要标记为已被插入元素,即hashTable[x]=true;
  • 处理完第index位,开始处理第index+1位,即generateP(index+1),记住,此时被插入元素跟随着函数执行;
  • 处理完index+1,元素x需还原状态以便for循环的下一步。
#include<iostream>
using namespace std;
const int maxn = 11;
int n,p[maxn], hashTable[maxn] = { false };

void generateP(int index) {
	//递归边界
	if (index == n + 1) {
		for (int i = 1;i <= n;i++) {
			cout << p[i];
		}
		cout << endl;
		return;
	}
	//枚举1~n,预将元素x存入p[index]中
	for (int x = 1;x <= n;x++) {
		if (hashTable[x] == false) {
			p[index] = x;
			hashTable[x] = true;
			generateP(index+1);
			hashTable[x] = false;
		}
	}
}

int main() {
	cin >> n;
	generateP(1);
	system("pause");
	return 0;
}

执行结果:

2、结合全排列实现八皇后

八皇后问题:

在一个8*8的棋盘里,每一行每一列只能存在一个皇后,否则就会被之前存在的皇后吃掉。皇后可以吃掉同一行同一列以及所在对角线上新加入的皇后。

分析:

  经过思考,不难发现以下事实:恰好每行每列各放置一个皇后。如果用p[]数组表示第index行皇后的列编号,则问题变成了全排列生成问题。剩下的事情就是排除那些对角线相同的结果。

排除对角线相同:

    int count = 0;//记录满足八皇后的结果
    if (index == n + 1) {
        bool flag = true;
        for (int i = 1;i <= n;i++) {
            for (int j = i + 1;j <= n;j++) {
                if (abs(i - j) == abs(p[i] - p[j])) {//绝对值相同即代表实在同一对角线上。(求解
                    flag = false;
                }
            }
        }
        if (flag) 
            count++;
        return count;
    }

 初步代码实现:

#include<iostream>
#include<stdlib.h>
#include<cmath>
using namespace std;
const int maxn = 11;
int n, p[maxn], hashTable[maxn] = { false };


int generateP(int index,int &count) {
	//递归边界
	if (index == n + 1) {
		bool flag = true;
		for (int i = 1;i <= n;i++) {
			for (int j = i + 1;j <= n;j++) {
				if (abs(i - j) == abs(p[i] - p[j])) {
					flag = false;
				}
			}
		}
		if (flag) 
			count++;
		return;
	}
	//枚举1~n,预将元素x存入p[index]中
	for (int x = 1;x <= n;x++) {
		if (hashTable[x] == false) {
			p[index] = x;
			hashTable[x] = true;
			generateP(index + 1,count);
			hashTable[x] = false;
		}
	}
}

int main() {
	cin >> n;
    int count=0;
	generateP(1,count);
	cout <<count<< endl;
	return 0;
}

全排列实现八皇后回溯法优化

猜你喜欢

转载自blog.csdn.net/Biubiuxin/article/details/82083855