C++八n皇后问题

要求解这一问题,最直接的方法就是穷举出8个皇后的所有摆放方法,然后依次检查其是否满足题中条件。棋盘共有8×8=64格,每次要选择8个格放皇后,因此总共有4426165368种组合。就算考虑到2个皇后无法同时出现在1行,即每行只能有1个皇后,那也有8的八次方16777216种组合。再加上2个皇后无法同时出现在1列,于是有8!=40320种组合。
相对地,使用下面所讲的回溯法求解八皇后问题,要远比遍历上述所有组合快得多。

  1. 在第1行的任意位置摆放皇后
  2. 在第2行中,选择不会被第1行皇后攻击的格子摆放第2个皇后
  3. 前i行放好i个皇后且保证它们不会互相攻击后,在第(i + 1)行寻找不会被任意一个皇后攻击的格子,摆放第(i + 1)个皇后
    如果不存在满足上述条件的格子,则返回第i行继续寻找下一个不会被攻击的格子。 如果不存在满足该条件的格子,则继续返回(i - 1)行

    像这样,系统地尝试所有可能得出正确解的状态,当发现当前状态得不到解时中断搜索并返回(以当时中断的位置为起点)上一状态继续搜索,这样的手法称为回溯。图的深度优先搜索就是基于回溯的算法。
    在八皇后问题中,为记录格子(i , j)是否会被其他皇后攻击,我们需要准备下列数组变量。这里的N=8。
变量 对应的状态
row[N] 如果row[x]为 NOT_FREE,则x行受到攻击
col[N] 如果col[x]为 NOT_FREE,则x列受到攻击
dpos[2N-1] 如果dpos[x]为 NOT_FREE,则斜向左下的x列受到攻击
dneg[2N-1] 如果dneg[x]为 NOT_FREE,则斜向右下的x列受到攻击

在这里插入图片描述只要row[i]、col[i]、 dpos[i + j]、 dneg[i-j+N-1]中有任意一个是 NOT_FREE,格子D(i, j)就会受到攻击。也就是说,当row[i]、col[i]、 dpos[i + j]、 dneg[i-j+N-1]全都为FREE时 ,皇后可以放置在该格子中。

#include<iostream>
#include<cassert>
using namespace std;
#define N 8
#define FREE -1
#define NOT_FREE 1

int row[N], col[N], dpos[2 * N - 1], dneg[2 * N - 1];

bool X[N][N];

void initialize() {
	for (int i = 0; i < N; i++) { row[i] = FREE, col[i] = FREE; };
	for (int i = 0; i < 2 * N - 1; i++) { dpos[i] = FREE; dneg[i] = FREE; };
}

void printBoard() {
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			if (X[i][j]) {
				if (row[i] != j) return;
			}
		}
	}
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			cout << ((row[i] == j) ? "Q" : ".");
		}
		cout << endl;
	}
}

void recursive(int i) {
	if (i == N) {
		printBoard(); return;
	}

	for (int j = 0; j < N; j++) {
		if (NOT_FREE == col[j] ||
			NOT_FREE == dpos[i + j] ||
			NOT_FREE == dneg[i - j + N - 1])continue;
		row[i] = j; col[j] = dpos[i + j] = dneg[i - j + N - 1] = NOT_FREE;
		recursive(i + 1);
		row[i] = col[j] = dpos[i + j] = dneg[i - j + N - 1] = FREE;
	}
}

int main() {
	initialize();

	for (int i = 0; i < N; i++)
		for (int j = 0; j < N; j++)X[i][j] = false;
	
	int k; cin >> k;
	for (int i = 0; i < k; i++) {
		int r, c; cin >> r >> c;
		X[r][c] = true;
	}
	recursive(0);
	
	//system("pause");
	return 0;
}
发布了54 篇原创文章 · 获赞 17 · 访问量 9199

猜你喜欢

转载自blog.csdn.net/qq_41979513/article/details/100112559
今日推荐