所谓回溯(backtracking)是通过系统地搜索求解问题的方法。这种方法适用于类似于八皇后这样的问题:求得问题的一个解比较困难,但是检查一个棋局是否构成解很容易。

不多说,放上n皇后的回溯问题代码:

//Queens.h
#define Queens_H
#ifndef Queeens_H #include <vector>
using namespace std; class Queens
{
public:
Queens(int size); //构造规模为n行n列的空棋盘
bool is_solved() const; //当前棋盘构成解
void print() const; //输出当前棋盘
bool unguarded(int col) const; //在(count,col)处放置皇后没有冲突
void insert(int col); //在(count,col)处放置皇后
void remove(int col); //删除(count,col)处放置的皇后
void solve_from(Queens &configuration); //n皇后问题回溯算法
int board_size; //棋盘规模
private:
int count; //当前棋盘上皇后个数
vector<vector<bool> > queen_square;
}; #endif
//Queens.cpp
#include "Queens.h"
#include <vector>
#include <iostream>
using namespace std; Queens::Queens(int size)
{
queen_square.resize(size);
int i;
for(i = 0;i < queen_square.size();i++)
{
queen_square[i].resize(size);
}
board_size = size;
count = 0; //还没有放置任何皇后
} bool Queens::is_solved() const
{
if(count == board_size)
return true;
else
return false;
} void Queens::print() const
{
cout << "下面是解决" << board_size << "皇后问题的一组解(\"O\"表示该位置有皇后,\"X\"表示给位置无皇后):" << endl;
int i,j;
for(i = 0;i < board_size;i++)
{
for(j = 0;j < board_size;j++)
{
if(queen_square[i][j])
cout << "O " ;
else
cout << "X " ;
}
cout << endl;
}
} bool Queens::unguarded(int col) const
{
//先把当前的坐标表示出来
int x = count;
int y = col;
int i,j;
for(i = 0;i < board_size;i++)
{
if(i != y && queen_square[x][i])
return false;
}
for(j = 0;j < board_size;j++)
{
if(j != x && queen_square[j][y])
return false;
}
for(i = 1;i < board_size;i++)
{
if(x - i >= 0 && x - i < board_size && y - i >= 0 && y - i < board_size)
{
if(queen_square[x-i][y-i])
return false;
}
if(x + i >= 0 && x + i < board_size && y + i >= 0 && y + i < board_size)
{
if(queen_square[x+i][y+i])
return false;
}
if(x + i >= 0 && x + i < board_size && y - i >= 0 && y - i < board_size)
{
if(queen_square[x+i][y-i])
return false;
}
if(x - i >= 0 && x - i < board_size && y + i >= 0 && y + i < board_size)
{
if(queen_square[x-i][y+i])
return false;
}
}
return true;
} void Queens::insert(int col)
{
queen_square[count][col] = true;
count++;
} void Queens::remove(int col)
{
count--;
queen_square[count][col] = false;
} void Queens::solve_from(Queens &configuration)
{
if(configuration.is_solved())
configuration.print();
else
{
for(int col = 0;col < configuration.board_size;col++)
{
if(configuration.unguarded(col))
{
configuration.insert(col); //在(count,col)处放置皇后
solve_from(configuration); //递归,继续求解
configuration.remove(col); //去掉先前在(count,col)处放置的皇后
}
}
}
}
//test.cpp
#include <iostream>
#include "Queens.h"
//#include <vector>
using namespace std; int main()
{
int n = 8; //尝试解决8皇后问题
Queens qq(n);
qq.solve_from(qq);
return 0;
}

回溯算法——解决n皇后问题的更多相关文章

  1. C语言回溯算法解决N皇后问题

    回溯算法的模型是 x++, not satisfy ? x-- : continue. 代码中x作列号,y[x]保存第x列上皇后放置的位置. #include<stdio.h> #incl ...

  2. 回溯算法之n皇后问题

    今天在看深度优先算法的时候,联想到DFS本质不就是一个递归回溯算法问题,只不过它是应用在图论上的.OK,写下这篇博文也是为了回顾一下回溯算法设计吧. 学习回溯算法问题,最为经典的问题我想应该就是八皇后 ...

  3. 算法刷题--回溯算法与N皇后

    所谓回溯算法,在笔者看来就是一种直接地思想----假设需要很多步操作才能求得最终的解,每一步操作又有很多种选择,那么我们就直接选择其中一种并依次深入下去.直到求得最终的结果,或是遇到明细的错误,回溯到 ...

  4. 回溯法解决N皇后问题(以四皇后为例)

    以4皇后为例,其他的N皇后问题以此类推.所谓4皇后问题就是求解如何在4×4的棋盘上无冲突的摆放4个皇后棋子.在国际象棋中,皇后的移动方式为横竖交叉的,因此在任意一个皇后所在位置的水平.竖直.以及45度 ...

  5. 用试探回溯法解决N皇后问题

    学校数据结构的课程实验之一. 数据结构:(其实只用了一个二维数组) 算法:深度优先搜索,试探回溯 需求分析: 设计一个在控制台窗口运行的“n皇后问题”解决方案生成器,要求实现以下功能: 由n*n个方块 ...

  6. C语言:试探算法解决“八皇后”问题

    #include <stdio.h> #define N 4 int solution[N], j, k, count, sols; int place(int row, int col) ...

  7. 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化

    上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来 ...

  8. 回溯算法-C#语言解决八皇后问题的写法与优化

    结合问题说方案,首先先说问题: 八皇后问题:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 嗯,这个问题已经被使用各种语言解 ...

  9. 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案

    八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同 ...

随机推荐

  1. 个人作业 - Week2 - 代码复审

    代码复审Check List 概要部分 代码能符合需求和规格说明么? 能完成1~1000000个数独的求解与生成,并能处理异常输入,满足需求. 代码设计是否有周全的考虑? 为输入单独开设了一个输入检测 ...

  2. git常用命令复习及其基本使用示例

    年后回来新上到项目,对于git的一些操作命令记得有点混乱了,所以特整理笔记如下: 一.git常用命令复习 查看当前分支:git branch (显示结果中带有*号的是当前分支)查看所有分支: git ...

  3. 使用 oracle pipelined 返回一个结果集;

    1.使用 create or replace package refcursor_pkg is -- Author : mr.yang -- Created : 5/14/2017 5:13:42 P ...

  4. 很有用的高级 Git 命令

    10 个很有用的高级 Git 命令 迄今,我已经使用Git很长一段时间了,考虑分享一些不管你是团队开发还是个人项目,都受用的高级git命令. 1. 输出最后一次提交的改变 这个命令,我经常使用它 来发 ...

  5. Js获取上一月份

    new Date(new Date().setMonth(new Date().getMonth() - 1))

  6. aes python加密

    # *_*coding:utf-8 *_* #AES-demo import base64 from Crypto.Cipher import AES ''' 采用AES对称加密算法 ''' # st ...

  7. Win2019 IPV6 支持存在问题

    1. 昨天晚上尝试 使用IPV6进行Oracle与SQLserver 的链接测试.从晚上六点到晚上八点测试环境一直不通. 后来换了服务器之后发现立即就可以了. 经过简单确认 怀疑Win server ...

  8. C语言版kafka消费者代码运行时异常kafka receive failed disconnected

    https://github.com/edenhill/librdkafka/wiki/Broker-version-compatibility如果使用了broker版本是0.8的话, 在运行例程时需 ...

  9. STM32CubeMX介绍、下载与安装

    一.简介 STM32CubeMX是一个配置STM32代码的工具,它把很多东西封装的比较好,硬件抽象层.中间层.示例代码等.现在ST公司升级和维护的库主要就是STM32CubeMX的HAL库和标准外设库 ...

  10. 一个非典型的Linux路由配置方案

    上周帮人解决了一个问题,这个问题绝对是非典型性的,采用了非常规的方法.虽然最终的方案非常不符合常规,非常不通用,充满了各种藏得很深的技巧或者说是trick,但是这个问题却是一个学习Linux路由的绝好 ...