关闭

八皇后问题的分析与解法

标签: 八皇后回溯
1483人阅读 评论(1) 收藏 举报
分类:

问题描述:


在8*8的国际象棋棋盘上,要求在每一行(或者每一列)放置一个皇后,且能做到在水平方向、竖直方向和斜方向都没有冲突。请列出所有解法。


根据上述描述,我们可以得到如果两个皇后Q1(x, y)和Q2(row, col)不符合要求,则以下四个条件之一必符合。

1 ) x == row

2 ) y == col

3 ) x + y == row + col (斜向正方向)

4 ) x - y == row - col(斜向反方向)


归纳出了程序的判断条件,下面用主流的回溯法来解决N皇后问题,这里是8皇后问题。回溯法也就是带有剪枝的深度优先遍历。

用回溯的方法解决8皇后问题的步骤为:
1)从第一列开始,为皇后找到安全的一行,然后开始下一列
2)如果在第n列出现死胡同,则完全放弃后面所有列的搜索,直接后退到上一列,进行回溯
3)如果在第8列上找到了安全位置,则棋局成功。

8个皇后都找到了安全位置代表棋局的成功,用一个长度为8的整数数组colume代表成功摆放的8个皇后,数组索引代表棋盘的col向量,而数组的值为棋盘的row向量,所以(row,col)的皇后可以表示为(colume[col],col)

#include <iostream>
#include <cmath>

#define QUEEN_NUM 8
int ResultCounter = 0;

void printResult(int colume[]);
bool check(int colume[], int col);
void QueenSolution(int colume[], int col);

int main(void){
    //数组colume中存放的是行值
    //即假设col[0]==3,表明第1列中皇后在第4行上
    int colume[QUEEN_NUM] = {0};
    QueenSolution(colume, 0);
    std::cout << "Solution Total Count: " << ResultCounter << std::endl;
}


//输出数组中的一组结果
void printResult(int colume[]){
    for(int i = 0; i < QUEEN_NUM; i++)
        std::cout << "(" << colume[i] << ", " << i << ") ";
    std::cout << std::endl;
    ResultCounter++;
}

//检查当前列col,在现有情况下,能否放置皇后
//如果是以下四种情况,就返回false
//1)x=row(在纵向不能有两个皇后)
//2)  y=col(横向)
//3)col + row = y+x;(斜向正方向)
//4)  col - row = y-x;(斜向反方向)
bool check(int colume[], int col){
    //因为提供的是列信息,我们就逐列进行检查
    for(int i = 0; i < col; i++)
    {
        if(colume[i] == colume[col] ||
           std::abs(colume[i] - colume[col]) == col - i )
            return false;
    }
    return true;
}

//尝试第col列上的所有解
//即在第col列的所有行上依次检验
//调用此函数时,表明从第0列到第col-1列都已经安置好了皇后
void QueenSolution(int colume[], int col){
    if(col == QUEEN_NUM)
    {
        printResult(colume);
        return;
    }

    //新的一列中,皇后有可能在任意一行
    for(int i = 0; i < QUEEN_NUM; i++)
    {
        colume[col] = i;  //将这个皇后放在第i行,进行检查
        if( check(colume, col) )
            QueenSolution(colume, col+1);
    }
}

PS.结果为92个。


0
0
查看评论

【C/C++】回溯经典算法之-->八皇后问题

一、八皇后问题 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方...
  • qq_31828515
  • qq_31828515
  • 2016-07-09 21:04
  • 13981

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

(一)题记 从去年下半年开始找工作,大大小小也被“鄙”试、“面”试了n多回了。说实话只怪自己并未对常见的笔试题、面试题进行准备,导致败下阵来。一门学问要想学透学精是需要时间的,慢慢来吧…… 第一次听到“八皇后”问题是在参加百度计算机视觉算法工程师面试时听中科院来面试的一个博士说的,当时隐约记得他是搞...
  • zssureqh
  • zssureqh
  • 2014-03-12 21:33
  • 33198

八皇后问题

1、介绍 先上张图来说明用回溯法解八皇后问题的每一步:          2、程序 对着严蔚敏的书写的,写好后运行竟然一次性成功了,没有任何bug,我鸡冻了。 上代码: // N皇后问题 #include using namespace s...
  • Justme0
  • Justme0
  • 2012-05-06 22:03
  • 33748

【算法复习二】八皇后问题 ---- 回溯

一,问题描述        在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。   二,分析     ...
  • tianshuai11
  • tianshuai11
  • 2012-05-04 16:49
  • 7886

8皇后问题(java算法实现)

最近总是无法静下心来集中精神干一些该干的事情,百般空虚之下,总得找了点有意义的东西填充一下,找了一道很久以前就听说挺经典的算法基础题来研究,就是下面那道题了,有一句话不知道怎么说来着,检验知识掌握与否的标准就在于你是否能把它清晰的传达出来。老实说,把整个思路写出来确实可以加深这个东西的理解。不过感觉...
  • zhong317
  • zhong317
  • 2009-09-23 22:37
  • 30396

回溯法:八皇后问题

八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成...
  • T_27080901
  • T_27080901
  • 2015-05-17 12:24
  • 4021

python基础: 遍历与八皇后问题浅析

python基础: 遍历与八皇后问题
  • u014386870
  • u014386870
  • 2015-03-10 15:02
  • 3446

经典回溯算法(八皇后问题)详解

八皇后问题,是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出: 在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上 (斜率为1),问有多少种摆法。高斯认为有76种方案。 1854年在柏林的象棋杂志...
  • u014082714
  • u014082714
  • 2015-04-06 13:58
  • 6857

八皇后问题(C语言版本)

八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
  • sxh850297968
  • sxh850297968
  • 2015-07-05 15:10
  • 14343

C++简单实现八皇后问题

近来无聊,想着几年前用c#实现的八皇后,是参考网上的答案,如今过了几年,想试试有没进步,用c++简单地实现。 八皇后问题,是回溯算法的经典例子,它的规则要求是同一行同一列同一条斜线不能有两个皇后,不然会相互攻击。这条件听上去不难吧,可运算量却是惊人的多啊。 首先,程序是算法加数据结构,我这程序的数据...
  • xanxus46
  • xanxus46
  • 2014-03-21 16:35
  • 6707
    个人资料
    • 访问:153125次
    • 积分:2642
    • 等级:
    • 排名:第16335名
    • 原创:109篇
    • 转载:20篇
    • 译文:1篇
    • 评论:45条
    最新评论