算法学步:回溯法-8皇后问题

问题描述:

有八个皇后(可以当成八个棋子),如何在 8*8 的棋盘中放置八个皇后,使得任意两个皇后都不在同一条横线、纵线或者斜线上

做法:

从第一行开始,一行一行地考虑,这样起码可以保证皇后不在同一行;

考虑下面的每一行的时候,需要让新增加的棋子不在前面添加的棋子的左下、正下、右下,即新增加的棋子的列不等于前面棋子的列,它的行号+列号不等于前面棋子的行号加列号(不在左下),|行号-列号|不等于之前棋子的|行号-列号|(不在右下);

如果该行所有位置都不符合要求,则回溯到前一行,改变皇后的位置,继续试探;

如果试探到最后一行,所有皇后摆放完毕,则直接打印出 8*8 的棋盘。最后一定要记得将棋盘恢复原样,避免影响下一次摆放。

程序代码:

/*回溯法,8皇后问题*/
#include<stdio.h>
#include<iostream>
#include<cmath>
#include<math.h>
using namespace std;
int weizhi[8]={0};//用来保存八个棋子的位置
int counts=0;
bool check(int hang, int lie);
void Queens(int nhang);
void print();
int main()
{
    Queens(0);
    cout<<"8皇后问题的解的个数为:"<<counts<<endl;
    return 0;
}

int Check(int line,int list){
    //遍历该行之前的所有行
    for (int index=0; index<line; index++) {
        //挨个取出前面行中皇后所在位置的列坐标
        int data=weizhi[index];
        //如果在同一列,该位置不能放
        if (list==data) {
            return 0;
        }
        //如果当前位置的斜上方有皇后,在一条斜线上,也不行
        if ((index+data)==(line+list)) {
            return 0;
        }
        //如果当前位置的斜下方有皇后,在一条斜线上,也不行
        if ((index-data)==(line-list)) {
            return 0;
        }
    }
    //如果以上情况都不是,当前位置就可以放皇后
    return 1;
}
//blog.csdn.net/yuer_xiao/article/details/82714734
void Queens(int nhang)//考虑第n行的棋子放置问题
{
    for(int lie=0;lie<8;lie++)
    {
        if(Check(nhang,lie))
        {
            weizhi[nhang]=lie;
            if(nhang==7)
            {
                counts+=1;
                print();
                weizhi[nhang]=0;
                return;
            }
            Queens(nhang+1);
            weizhi[nhang]=0;
        }
    }
    return;//考虑完全部8个位置,没有符合要求的,返回上一行调用Queens(nhang+1)的地方,使上一行的位置数+1,其实此处不用写return,执行完成之后
}

void print()
{
    for (int line = 0; line < 8; line++)
    {
        int list;
        for (list = 0; list < weizhi[line]; list++)
            printf("0");
        printf("#");
        for (list = weizhi[line] + 1; list < 8; list++){
            printf("0");
        }
        printf("\n");
    }
    printf("================\n");
}

原文地址:https://www.cnblogs.com/za-chen/p/12024927.html

时间: 2024-10-22 20:13:14

算法学步:回溯法-8皇后问题的相关文章

五大经典算法之回溯法

一.基本概念 ??回溯法,又称为试探法,按选优条件向前不断搜索,以达到目标.但是当探索到某一步时,如果发现原先选择并不优或达不到目标,就会退回一步重新选择,这种达不到目的就退回再走的算法称为回溯法. 与穷举法的区别和联系: 相同点:它们都是基于试探的. 区别:穷举法要将一个解的各个部分全部生成后,才检查是否满足条件,若不满足,则直接放弃该完整解,然后再尝试另一个可能的完整解,它并没有沿着一个可能的完整解的各个部分逐步回退生成解的过程.而对于回溯法,一个解的各个部分是逐步生成的,当发现当前生成的某

【基础算法】回溯法与八皇后问题

在国际象棋中,皇后是最强大的一枚棋子,可以吃掉与其在同一行.列和斜线的敌方棋子.比中国象棋里的车强几百倍,比她那没用的老公更是强的飞起(国王只能前后左右斜线走一格).上图右边高大的棋子即为皇后. 八皇后问题是这样一个问题:将八个皇后摆在一张8*8的国际象棋棋盘上,使每个皇后都无法吃掉别的皇后,一共有多少种摆法?此问题在1848年由棋手马克斯·贝瑟尔提出,岂止是有年头,简直就是有年头,82年的拉菲分分钟被秒的渣都不剩. 八皇后问题是典型的回溯法解决的问题,我们以这个问题为例介绍回溯法. 所谓回溯法

回溯法之八皇后问题简单理解

回溯法,简单理解就是有源可溯.基本思想要借鉴穷举法,但是它不是一味地穷举,当发现某一步不符合条件时,这一步后面的穷举操作就不进行了(俗称“剪枝”),我自己把它叫做动态穷举法.假设第一个步骤可行,那么执行第二个步骤,第三个......如果其中第三个步骤不行,那么我们再回过来(回溯),第二个步骤换一种方法尝试,然后再重新第三个步骤,第四个......直到完成任务要求为止. 这里,以八皇后问题为例.试图把回溯法讲清楚. 注意:递归应该是一种算法结构,回溯法是一种算法思想. 何为八皇后问题? (百度百科

回溯法---n皇后问题(4)

body { font-family: 微软雅黑,"Microsoft YaHei", Georgia,Helvetica,Arial,sans-serif,宋体, PMingLiU,serif; font-size: 10.5pt; line-height: 1.5; } html, body { } h1 { font-size:1.5em; font-weight:bold; } h2 { font-size:1.4em; font-weight:bold; } h3 { fon

马踏棋盘算法递归+回溯法实现 C语言

r为矩阵的行,c为矩阵的列 将结果输出到当前目录下的results.txt(需要提前建好). 结果将给出:1.是否存在路径使马可以按要求走遍所有的方格: 2.解的总数: 3.程序执行的时间: #include<stdio.h> #include <stdlib.h> #include <time.h> #define r 2 #define c 4 int flag[r][c]={0};//存放马跳路径的二维数组 int arr[r][c]={0}; int x[8]=

每天刷个算法题20160519:回溯法解八皇后

版权所有.所有权利保留. 欢迎转载,转载时请注明出处: http://blog.csdn.net/xiaofei_it/article/details/51502622 为了防止思维僵化,每天刷个算法题.已经刷了几天了,现在发点代码. 我已经建了一个开源项目,每天的题目都在里面: https://github.com/Xiaofei-it/Algorithms 绝大部分算法都是我自己写的,没有参考网上通用代码.读者可能会觉得有的代码晦涩难懂,因为那是我自己的理解. 最近几天都是在写一些原来的东西

回溯法求解八皇后问题---(初步、未优化)

首先介绍一下回溯算法: 定义来自<百度百科>......名字着很高大上,实际上就是试探法,逐步试错找到最终的可行解. 重要的一点是解空间通常是在搜索可行解过程中动态产生的,所以程序中通常利用到递归的算法,如后面介绍的八皇后问题.这点区别与于前段时间所写的模拟退火算法,模拟退火是首先确定解空间,然后以一定的概率接受当前发现的次优解,从而有更大的可能避免局部最优而得到全局最优. 简单介绍一下八皇后问题: 在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或

五大常用算法之四:回溯法

(转自:http://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741376.html) 1.概念 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径. 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”. 许

算法思想之回溯法

一.概念 回溯:当把问题分成若干步骤并递归求解时,如果当期步骤没有合法选择,则函数将返回上一级递归调用,这种现象称为回溯. 回溯算法应用范围:只要把待求解问题分成不太多的步骤,每个步骤又只有不太多的选择,即可以考虑用回溯法. 回溯算法实际上是一个递归枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径. 回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不