OpenJudge | 八皇后问题

总时间限制: 10000ms 内存限制: 65536kB

描述

在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方。

输入

无输入。

输出

按给定顺序和格式输出所有八皇后问题的解(见Sample Output)。

样例输入

cpp 复制代码
(null)

样例输出

cpp 复制代码
No. 1
1 0 0 0 0 0 0 0 
0 0 0 0 0 0 1 0 
0 0 0 0 1 0 0 0 
0 0 0 0 0 0 0 1 
0 1 0 0 0 0 0 0 
0 0 0 1 0 0 0 0 
0 0 0 0 0 1 0 0 
0 0 1 0 0 0 0 0 
No. 2
1 0 0 0 0 0 0 0 
0 0 0 0 0 0 1 0 
0 0 0 1 0 0 0 0 
0 0 0 0 0 1 0 0 
0 0 0 0 0 0 0 1 
0 1 0 0 0 0 0 0 
0 0 0 0 1 0 0 0 
0 0 1 0 0 0 0 0 
No. 3
1 0 0 0 0 0 0 0 
0 0 0 0 0 1 0 0 
0 0 0 0 0 0 0 1 
0 0 1 0 0 0 0 0 
0 0 0 0 0 0 1 0 
0 0 0 1 0 0 0 0 
0 1 0 0 0 0 0 0 
0 0 0 0 1 0 0 0 
No. 4
1 0 0 0 0 0 0 0 
0 0 0 0 1 0 0 0 
0 0 0 0 0 0 0 1 
0 0 0 0 0 1 0 0 
0 0 1 0 0 0 0 0 
0 0 0 0 0 0 1 0 
0 1 0 0 0 0 0 0 
0 0 0 1 0 0 0 0 
No. 5
0 0 0 0 0 1 0 0 
1 0 0 0 0 0 0 0 
0 0 0 0 1 0 0 0 
0 1 0 0 0 0 0 0 
0 0 0 0 0 0 0 1 
0 0 1 0 0 0 0 0 
0 0 0 0 0 0 1 0 
0 0 0 1 0 0 0 0 
No. 6
0 0 0 1 0 0 0 0 
1 0 0 0 0 0 0 0 
0 0 0 0 1 0 0 0 
0 0 0 0 0 0 0 1 
0 1 0 0 0 0 0 0 
0 0 0 0 0 0 1 0 
0 0 1 0 0 0 0 0 
0 0 0 0 0 1 0 0 
No. 7
0 0 0 0 1 0 0 0 
1 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 1 
0 0 0 1 0 0 0 0 
0 1 0 0 0 0 0 0 
0 0 0 0 0 0 1 0 
0 0 1 0 0 0 0 0 
0 0 0 0 0 1 0 0 
No. 8
0 0 1 0 0 0 0 0 
1 0 0 0 0 0 0 0 
0 0 0 0 0 0 1 0 
0 0 0 0 1 0 0 0 
0 0 0 0 0 0 0 1 
0 1 0 0 0 0 0 0 
0 0 0 1 0 0 0 0 
0 0 0 0 0 1 0 0 
No. 9
0 0 0 0 1 0 0 0 
1 0 0 0 0 0 0 0 
0 0 0 1 0 0 0 0 
0 0 0 0 0 1 0 0 
0 0 0 0 0 0 0 1 
0 1 0 0 0 0 0 0 
0 0 0 0 0 0 1 0 
0 0 1 0 0 0 0 0 
...以下省略

提示

此题可使用函数递归调用的方法求解。

来源

计算概论05

解析

何为八皇后

八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。

突破口

任两个皇后都不能处于同一条横行、纵行或斜线上

  1. 同一行和同一列两者总有一个是不会重复的,看你以什么作为递归的传入条件。
  2. 困难点在与斜线上------所谓斜线上,包括以上一个皇后所在的位置为交点 k = 1 k=1 k=1和 k = − 1 k=-1 k=−1这两条斜线。
    其中, k = 1 k=1 k=1的斜线可用 y 1 − x 1 = y 2 − x 2 y_1-x_1 = y_2-x_2 y1−x1=y2−x2来判断, k = − 1 k=-1 k=−1的斜线可用 y 1 + x 1 = y 2 + x 2 y_1+x_1 = y_2+x_2 y1+x1=y2+x2来判断

Code

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

array<pair<int, int>, 8> record = {};
array<int, 8> yR = {0};
array<array<bool, 8>, 8> res;

bool judge(int x, int y) {
	if(yR[y] == 1) return false;
	for(int i = 0; i < x; i++) {
		if(record[i].first - record[i].second == x - y) return false;
	}
	for(int i = 0; i < x; i++) {
		if(record[i].first + record[i].second == x + y) return false;
	}
	return true;
}

void dfs(int x, int *count) {
	if(x >= 8) {
		printf("No. %d\n", ++(*count));
		for(int i = 0; i < 8; ++i) {
			for(int j = 0; j < 8; ++j) {
				printf("%d ", res[i][j]);
			}
			printf("\n");
		}
		return;
	}
	for(int y = 0; y < 8; ++y) {
		if(judge(x, y) == 0) continue;
		record[x].first = x;
		record[x].second = y;
		res[y][x] = 1;
		yR[y] = 1;
		dfs(x+1, count);
		res[y][x] = 0;
		yR[y] = 0;
		
	}

}

int main() {
	int count = 0;
	for(int i = 0; i < 8; i++) {
		res[i].fill(0);
	}	
	dfs(0, &count);
}

鸣谢

连烟的递归从入门到精通

  1. DFS、回溯算法(26分钟)
相关推荐
郝学胜_神的一滴18 分钟前
CMake 27:缓存变量的特性、语法、类型与实操全解
c++·cmake
kisshyshy24 分钟前
从递归到迭代,一文吃透二叉树的核心知识与 JavaScript 实现
javascript·算法·代码规范
To_OC11 小时前
LC 49 字母异位词分组:想到哈希表很简单,选对 key 才是精髓
javascript·算法·leetcode
用户9385156350716 小时前
从 O(n²) 到 O(nlogn):一文读懂快速排序的“快”与“妙”
javascript·算法
To_OC17 小时前
手写快排次次翻车?别死背快排模板了,这才是面试官想听的底层逻辑
javascript·算法·排序算法
饼干哥哥18 小时前
Reddit VOC调研太慢?搭一个AI专家团队半小时洞察任何品类|以猫用饮水机为例
人工智能·算法·ai编程
地平线开发者19 小时前
Transformer模型部署之性能优化指南
算法
地平线开发者20 小时前
人在途中:从“编译失败”到“模型可落地”——CUDA 自定义算子
算法·自动驾驶
半个落月1 天前
从递归到快速排序:用 JavaScript 把分治思想讲明白
javascript·算法·面试
小月土星1 天前
JavaScript 快速排序:从 pivot、双指针到分治思想
javascript·算法·面试