代码先锋网 代码片段及技术文章聚合

《算法笔记》codeup 100000583 问题 D: 八皇后 (N皇后代码解析)

技术标签: codeup

思路:

从棋盘的第一列开始,尝试在当前列的每一行摆放皇后。如果当前在行列上摆放暂时不会引起冲突,则保存摆放的位置。然后进入下一行重复上述操作,直到每一列都完成操作。

解答:

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

/*
    从棋盘的第一列开始,尝试在当前列的每一行摆放皇后。
    如果当前在行列上摆放暂时不会引起冲突,则保存摆放的位置。
    然后进入下一行重复上述操作,直到每一列都完成操作。
*/

int plan_num = 0;                  // 方案数量
int row_of_colm[11];               // 0元素弃置,第i个元素表示第i列上的皇后所在行的序号
bool if_occupied[11] = {false};    // 0元素弃置,第1到10个元素分别表示第1到10行时候已经放了皇后
int plan[92];                      // 数组的每个元素表示一种方案

void NQueneP(int colm, int n) {    // colmumn表示列号
    if(colm == n + 1) {	           // 递归边界
		plan_num++;
		for(int i = 1; i <= n; i++) {  // 摆放方案保存为一个整数
            plan[plan_num] += row_of_colm[i] * pow(10, i - 1);
        }
		return;                    //返回上一层递归出口 
	} 

	//从第一行开始枚举试图摆放皇后 
	for(int row = 1; row <= n; row++) {
		if(if_occupied[row] == false) {    //当前行未被占用 
			bool flag = true;              //试图在colm列row行摆放皇后
            
			for(int pre = 1; pre < colm; pre++) {  // 此时第1列到第colm-1列已处理完,这些列上的皇后已摆好,第i列上的皇后所在行号保存在row_of_colm[i]中,遍历前面的列检查是否会与当前行列上的皇后有对角冲突
				if(abs(colm - pre) == abs(row - row_of_colm[pre])) {  // 如果前面某皇后的行列与当前行列的差的绝对值相当,则对角冲突
					flag = false;          //不能在当前行列摆放 
					break;  
				}
			}

			//若为false,则不能在当前行列摆放,基于进入本次递归前确定的摆放位置加上本次探查的位置组成的摆放方案已经不可能成功,无需进一步摆放下去,直接进入下一行
			if(flag == true) {
				row_of_colm[colm] = row;            //在colm列row行摆放皇后 
				if_occupied[row] = true;            //标记row行已被占用 
				NQueneP(colm+1, n);                 //进行下一列处理 

                // 到达此处表明基于该行列的情况已经探查完,循环准备进入下一行
				if_occupied[row] = false;           // 清除占用标记 
			}
		}
	} 
}
int main(){
	int n = 8;       // 皇后数
	NQueneP(1, n);   //从第一列开始摆皇后 
    sort(plan + 1, plan + (plan_num + 1));

    int test_num;
    while(scanf("%d", &test_num) != EOF) {
        for(int i = 1; i <= test_num; i++) {
            int index;
            scanf("%d", &index);
            printf("%d\n", plan[index]);
        }
    }
    /*
	cout << "共有" << plan_num << "种摆法" << endl;
    for(int i = 0; i <= 92; i++) {
        printf("%d  %d\n", i, plan[i]);
    }
    */
	return 0;
} 

笔记:

  1. 代码是比照《算法笔记》中对应部分写的,原书中的代码的变量名让人有点难以理解代码的逻辑,实际上就是遍历每一列,在每一列上遍历每一行。
  2. 我个人认为书中提到这段代码的回溯思想,应该是体现在某个位置上发现会与之前摆好的皇后起冲突后,就跳过进一步的摆法,直接探查当前列下一行。但这好像与书中说的“五皇后时摆好351后可以发现剩下两个位置一定会冲突”不太一样,实际上我都不太明白它是怎样发现一定会冲突。
  3. codeup编译错误可以点击查看提示。

 

版权声明:本文为Zen_Ivan原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Zen_Ivan/article/details/107144016

智能推荐

问题 D: 八皇后

题目描述   会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。  对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。 给出...

问题 D: 八皇后

题目描述   会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。 给出一个数b,要...

问题 D: 八皇后

题目链接:http://codeup.cn/problem.php?cid=100000583&pid=3 题目描述 会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2…b8,其中b...

问题 D: 八皇后

题目链接...

【算法笔记4.3小节-递归】问题 D: 八皇后

题目链接:http://codeup.cn/problem.php?cid=100000583&pid=3 题目描述   会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其...

猜你喜欢

PAT-算法笔记-问题 D: 八皇后

题目描述 会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2…b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。 给出一个数b,要求输...

问题 D: 八皇后 递归 (******)

时间限制: 1 Sec 内存限制: 32 MB 提交: 730 解决: 385 [提交][状态][讨论版][命题人:外部导入] 题目描述 会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2…...

2046问题 D: 八皇后

题目描述   会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。  对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。 给出...

递归问题 D: 八皇后

题目描述 会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2…b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。 给出一个数b,要求输...

[算法]八皇后问题

问题描述: 八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当n = 1或n ≥ 4时问题有解。 解法: 最初的想法是暴力解法,即每...