noi 递归之八皇后问题(一些关于“棋盘”的规律)

题源:http://noi.openjudge.cn/ch0205/1700/
1700:八皇后问题
总时间限制: 10000ms 内存限制: 65536kB
描述
在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方。
输入
无输入。
输出
按给定顺序和格式输出所有八皇后问题的解(见Sample Output)。
样例输入
样例输出
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
…以下省略
提示
此题可使用函数递归调用的方法求解。
首先我们要先了解一些小技巧:
noi 递归之八皇后问题(一些关于“棋盘”的规律)_第1张图片(关于棋盘的一些规律)
我们从每一行开始放置皇后,然后将这个皇后所在的列,上对角线,下对角线进行标记,查找合适的方案。

#include 
#include 
#include 
#include
#include
#include 
using namespace std;
int num=1;\\记录解的个数
int hang[8]={
     0};\\第n行的皇后所在(列)的位置
bool lie[8]={
     1,1,1,1,1,1,1,1};\\标记皇后所占领的列
bool shang[15]={
     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};\\标记皇后所占领的上对角线
bool xia[15]={
     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};\\标记皇后所占领的列对角线
void print(){
     \\打印全部皇后可以摆放的可能情况
	printf("No. %d\n",num);
	num++;
	int qpan[8][8]={
     0};\\找出皇后所在位置
	for(int i=0;i<8;i++){
     
		qpan[hang[i]][i]=1;\\把皇后在的位置标记下来
	}
	for(int i=0;i<8;i++){
     
		for(int j=0;j<8;j++){
     
			printf("%d ",qpan[i][j]);\\输出全部皇后摆放的一种情况
		}
		printf("\n");
	}
}
void queen(int n){
     
	for(int l=0;l<8;l++){
     //每个皇后都有8种可以放置的列
		if(lie[l]&&shang[n-l+7]&&xia[n+l]){
     \\判断下一个皇后和前面所有皇后所在位置有没有冲突
			hang[n]=l;\\第n行的皇后所在(列l)的位置
			lie[l]=0;\\记录此皇后占领的列
			shang[n-l+7]=0;\\记录此皇后占领的上对角线
			xia[n+l]=0;\\记录此皇后占领的下对角线
			if(n<7){
     \\若不是最后一个皇后,那就开始递归啦
				queen(n+1);
			}
			else print();\\若循环到了最后一个皇后那就答应棋盘叭
			lie[l]=1;\\这三步是在清空前一步棋盘,试图寻找其他可能存在的情况,毕竟每行皇后放置的列数是多种可能的嘛
			shang[n-l+7]=1;
			xia[n+l]=1;
		}
	}
}
int main() {
     
	queen(0);
return 0;
}

你可能感兴趣的:(noi做题,算法)