1.问题描述:

搜索入门——八皇后问题
搜索入门——八皇后问题

2.问题分析

首先八皇后问题相信大家多多少少都有所了解,毕竟是比较经典的回溯搜索问题了。八皇后的规定是每一枚皇后的行列以及左斜线,右斜线上仅此只能存在一个。和国际象棋中的皇后规则一样。如图:
搜索入门——八皇后问题
画X的是不能放置皇后的
如果我们用搜索来做的话我们可以搜索行,然后通过枚举列来判断是否能放,这里最大的难点是找到左斜线以及右斜线的规律,可以看到
左斜线的坐标分别为(1,1),(2,2)(3,3)(4,4)(5,5)(6,6)观察会发现行坐标-纵坐标都为0,由此我们可推断左斜线规律应该判断行坐标 - 列坐标.但是因为是相减有可能为负数,有可能
右斜线的坐标分别为(1,5),(2,4),(3,3)(4,2)(5,1)可观察出每个坐标都为行坐标加列坐标。
这样就可以判断皇后的行,列,左斜,右斜是否冲突即可。
搜索的出口当然是行超过输入的N那么就找到一组可行解了,我们设置变量total就是可以摆放皇后的方案。小于等于3我们将其输出,在输出之前设定一个ans数组保存列的坐标即可。

3.代码:

#include <iostream>
#include <cstdio>
using namespace std;

bool vis1[1005],vis2[1005],vis3[1005];   //vis1表示列是否能放,vis2表示左斜线是否能放,vis3表示右斜线是否能放
int ans[1000005];
int N,total;

void dfs(int x) {
	if (x > N) {
		total++;
		if (total <= 3) {
			for (int i = 1; i <= N; i++) {
				printf("%d ",ans[i]);
			}
			printf("\n");
		}
	}
	
	for (int i = 1; i <= N; i++) {
		if (!vis1[i] && !vis2[x - i + N] && !vis3[x + i]) {
			ans[x] = i;
			vis1[i] = 1;
			vis2[x - i + N] = 1;
			vis3[x + i] = 1;
			dfs(x + 1);
			vis1[i] = 0;
			vis2[x - i + N] = 0;
			vis3[x + i] = 0;
		}
	}
}

int main() {
	scanf("%d",&N);
	dfs(1);
	printf("%d\n",total);
	return 0;
}

测试地址:https://www.luogu.org/problemnew/show/P1219
欢迎关注Blog:
www.lyxueit.com

相关文章: