经典算法---8皇后问题的C++实现

其实8皇后问题,很好理解,8X8的棋盘上面,放8只皇后,使他们之间不会相互攻击,具体的定义,渊源可以查看百度百科八皇后问题

本科时候学数据结构的时候就接触过这个经典算法,不过当时没怎么听明白,或者说知道是个回溯的思想,却不知道该怎么实现,原谅我只是个小白。今天上振动力学的时候,闲着没事突然想到了这个问题,顺手写下了伪代码,到实验室调试一下,基本就出来了。

调试过程中遇到了两个bug,在代码中已经注明了(这里标记下,方便自己以后能方便找到重点)

1.退出条件中有个等号

2.需要恢复现场

另外

1.算法相对应的数据结构实际上是一个1维数组,存储每行所选取的列标号。

2.其实我们将其写成了N皇后问题,也就是说通过修改 构造参数,我们可以实现 其他n个皇后问题的求解。

3.网上看到有用二维数组实现的,就顺便拿过来了

算法学习笔记之三:八皇后问题(递归、回溯)

4.还看到一篇和我用的方法相似的,也拿过来

经典算法(1)——8皇后问题求解(回溯法)

感觉虽然有很多注释,不过还是不太容易看明白,不过话说大家看我的代码兴许也是这样吧。23333333333333

运行结果图:

代码如下:

// ----------------------【NQueen.h】-------------------
#pragma once
class CNQueen
{
public:
    CNQueen();
    CNQueen(int num);
    ~CNQueen();

public:
    void SolveResult();

private:
    bool IsOK(int row, int col);
    void output();
    bool init(int num);
    void TraceBack(int CurRow);

private:
    int m_num;
    int * m_RowSelect;

    int m_solution_num;
};

// ------------------------【NQueen.cpp】----------------------------
#include "NQueen.h"
#include <cstdio>
#include <string>

bool CNQueen::init(int num)
{
    m_solution_num = 0;

    m_RowSelect = new int[m_num];
    memset(m_RowSelect, 0, sizeof(m_RowSelect));

    return true;
}

CNQueen::CNQueen(int num) :m_num(num)
{
    init(m_num);
}

CNQueen::~CNQueen()
{
    if (m_RowSelect)
        delete [] m_RowSelect;
}

// ---------------------------------【回溯求解】----------------------------
void CNQueen::TraceBack(int CurRow)
{
    // 这里需要有个 等号操作,我说怎么死活没结果
    if (CurRow >= m_num)
    {
        m_solution_num++;
        output();
        return;
    }

    for (int j = 0; j != m_num; j++)
    {
        m_RowSelect[CurRow] = j;
        if (IsOK(CurRow, j))
        {
            CurRow++;
            TraceBack(CurRow);
            CurRow--;               // 恢复现场
        }
    }

}

// ---------------------------------【剪枝函数】----------------------------
bool CNQueen::IsOK(int row, int col)
{
    for (int k = 0; k != row; k++)
    {
        if (col == m_RowSelect[k])    // 列
            return false;

        if (row - k == col - m_RowSelect[k])  // 斜线
            return false;

        if (row - k == m_RowSelect[k] - col)
            return false;
    }

    return true;
}

// ---------------------------------【显示 解的分布 】----------------------------
void CNQueen::output()
{
    FILE * fd = NULL;

    if (m_solution_num == 1)
    {
        fd = fopen("output.txt", "wt");
        fprintf(fd, "-----------------------------%d皇后问题求解-----------------------------------\n",
            m_num);
    }
    else
        fd = fopen("output.txt", "at+");

    fprintf(fd, "找到第%d组可行解\n", m_solution_num);
    for (int i = 0; i != m_num; i++)
    {
        for (int j = 0; j != m_num; j++)
        {
            if (m_RowSelect[i] == j)
                fprintf(fd, "\tQ");
            else
                fprintf(fd, "\t*");
        }
        fprintf(fd, "\n");
    }
    fclose(fd);
    //system("pause");
}

// ---------------------------------【求解 并显示在屏幕上】----------------------------
void CNQueen::SolveResult()
{
    TraceBack(0);

    if (m_solution_num == 0)
        fprintf(stdout, "无解\n");
    else
        fprintf(stdout, "找到%d组解,放在output.txt文件中\n", m_solution_num);
}
// ---------------------------------【八皇后问题 main.cpp】----------------------------
//  @   author          :       zhyh2010
//  @   date            :       20150519
//  @   description     :       主要基于回溯的思想, C++ 实现
//  @   version         :       1.0
// ---------------------------------【八皇后问题 end】----------------------------

#include "NQueen.h"
#include <windows.h>

int main(int arg, char ** argv)
{
    CNQueen instance(2);
    instance.SolveResult();
    system("pause");
    return 0;
}
时间: 2024-09-30 20:40:20

经典算法---8皇后问题的C++实现的相关文章

数据挖掘十大经典算法

一. C4.5  C4.5算法是机器学习算法中的一种分类决策树算法,其核心算法是ID3 算法.   C4.5算法继承了ID3算法的优点,并在以下几方面对ID3算法进行了改进: 1) 用信息增益率来选择属性,克服了用信息增益选择属性时偏向选择取值多的属性的不足: 2) 在树构造过程中进行剪枝: 3) 能够完成对连续属性的离散化处理: 4) 能够对不完整数据进行处理. C4.5算法有如下优点:产生的分类规则易于理解,准确率较高.其缺点是:在构造树的过程中,需要对数据集进行多次的顺序扫描和排序,因而导

【经典算法大全】收集51种经典算法 初学者必备

<经典算法大全>是一款IOS平台的应用.里面收录了51种常用算法,都是一些基础问题.博主觊觎了好久,可悲哀的是博主没有苹果,所以从网上下了老奔的整理版并且每个都手敲了一遍. 虽然网上也有博客贴了出来,但是自己写写感觉总是好的.现在分享个大家. 代码和运行结果难免有出错的地方,请大家多多包涵. 1.河内之塔(汉诺塔) 2.费式数列 3.巴斯卡三角形 4.三色棋 5.老鼠走迷宫(1) 6.老鼠走迷宫(2) 7.骑士走棋盘 8.八皇后 9.八枚银币 10.生命游戏 11.字串核对 12.双色河内塔,

经典算法大全

原文地址:经典算法大全 作者:liurhyme 经                                                                    典                                                                    算                                                                    法                  

经典算法-回顾(前十)

关于 曾经的48种经典算法与23种常用设计模式相信都不陌生了,不过好久没看了而且当时看的时候也没有整理出来,现在就慢慢整理出来(后续会慢慢更新,这里只是对经典算法进行整理): 目录: 1.河内之塔_TowersOfHanoi2.费氏数列_Fibonacci3.巴斯卡三角形4.三色棋5.老鼠走迷官16.老鼠走迷官27.骑士走棋盘_KnightTour8.八皇后9.八枚银币10.生命游戏 先来看看基本说明和解法: 1.河内之塔_TowersOfHanoi 说明 河内之塔(Towers of Hano

经典算法题每日演练——第一题 百钱买百鸡

原文:经典算法题每日演练--第一题 百钱买百鸡 百钱买百鸡的问题算是一套非常经典的不定方程的问题,题目很简单:公鸡5文钱一只,母鸡3文钱一只,小鸡3只一文钱, 用100文钱买一百只鸡,其中公鸡,母鸡,小鸡都必须要有,问公鸡,母鸡,小鸡要买多少只刚好凑足100文钱. 分析:估计现在小学生都能手工推算这套题,只不过我们用计算机来推算,我们可以设公鸡为x,母鸡为y,小鸡为z,那么我们 可以得出如下的不定方程, x+y+z=100, 5x+3y+z/3=100, 下面再看看x,y,z的取值范围. 由于只

动态展示十大经典算法

算法一:快速排序算法 快速排序是由东尼·霍尔所发展的一种排序算法.在平均状况下,排序n个项目要Ο(nlogn)次比较.在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见.事实上,快速排序通常明显比其他Ο(nlogn)算法更快,因为它的内部循环(innerloop)可以在大部分的架构上很有效率地被实现出来. 快速排序使用分治法(Divideandconquer)策略来把一个串行(list)分为两个子串行(sub-lists). 算法步骤: 1.从数列中挑出一个元素,称为“基准”(pivot),

数据挖掘领域十大经典算法初探

译者:July   二零一一年一月十五日 ----------------------------------------- 参考文献:国际权威的学术组织ICDM,于06年12月年评选出的数据挖掘领域的十大经典算法:C4.5, k-Means, SVM, Apriori, EM, PageRank, AdaBoost, kNN, Naive Bayes, and CART.==============博主说明:1.原文献非最新文章,只是本人向来对算法比较敏感.感兴趣,便把原文细看了下,翻译过程中

【白话经典算法系列之十七】 数组中只出现一次的数 其他三次

本文地址:http://blog.csdn.net/morewindows/article/details/12684497转载请标明出处,谢谢. 欢迎关注微博:http://weibo.com/MoreWindows 首先看看题目要求: 数组A中,除了某一个数字x之外,其他数字都出现了三次,而x出现了一次.请给出最快的方法找到x. 这个题目非常有意思,在本人博客中有<位操作基础篇之位操作全面总结>这篇文章介绍了使用位操作的异或来解决——数组中其他数字出现二次,而x出现一次,找出x.有<

三白话经典算法系列 Shell排序实现

山是包插入的精髓排序排序.这种方法,也被称为窄增量排序,因为DL.Shell至1959提出命名. 该方法的基本思想是:先将整个待排元素序列切割成若干个子序列(由相隔某个"增量"的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序. 由于直接插入排序在元素基本有序的情况下(接近最好情况),效率是非常高的,因此希尔排序在时间效率上比前两种方法有较大提高. 以n=10的一个数组49, 38, 65, 97