当前位置:首页 > 题解目录 > 正文内容

八皇后问题

亿万年的星光5年前 (2021-01-28)题解目录4865

【题目描述】

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

【输入描述】

【输出描述】

一共有多少种摆法

【样例输入】

【样例输出】

92

【题目分析】

(1)框架分析

放置第i个(行)皇后的算法为:
int search(i);
 {
     int j;
   for (第i个皇后的位置j=1;j<=8;j++ )	    //在本行的8列中去试
   if (本行本列允许放置皇后)
    {
     放置第i个皇后;
                  对放置皇后的位置进行标记;
     if (i==8) 输出	                              //已经放完个皇后
        else search(i+1);                //放置第i+1个皇后
     对放置皇后的位置释放标记,尝试下一个位置是否可行;
    }
 }

(2)

主要解决几个问题:
冲突:包括行、列、两条对角线
行:规定每行放一个皇后,不会造成行上的冲突
列:当第col列被某个皇后占领后,则同一列上所有位置不在放皇后,要把    flag[col] 置为被占领状态。
对角线:对角线有两个方向。当第n行第col列皇后占领后,上下对角线标记               为被占领状态。

规律:左上到右下,我们叫主对角线,同一主对角线i-j是个常数。右上到左下,我们称为副对角线,同一副对角线i+j是个常数。所以,

左上到右下:   i-j+7  (C++ 不支持负数)
右上到左上:   i+j

(3)

1.初始化(清除棋盘)
2.循环8次
      放置一个皇后;      
      检查是否满足条件,如满足,登记皇后位置;      
      如不满足,则退回,增加一步后在放皇后。
3. 知道放置最后一个皇后

【参考代码1】

用col表示列,L_diagonal表示主对角线(就是左上到右下),R_diagonal表示副对角线(就是右上到左下)

#include<iostream>
using namespace std;
int col[10],L_diagonal[10],R_diagonal[10]; //分别表示标记数组,列数组,主对角线数组,副对角线数组
int ans[10]; //结果数组
int sum;
int dfs(int i)//用i来表示皇后所处的行位置
{
   int j; //用j表示皇后所处的列位置
   for(j=1;j<=8;j++)
       if((col[j]==0)&&(L_diagonal[i-j+7]==0)&& (R_diagonal[i+j]==0))// 列、主对角线、副对角线没有被占领过
       {
           ans[i]=j; //在当前(i,j)位置上摆放一个皇后
           col[j]=1; //占领当前(i,j)所在的列
           L_diagonal[i-j+7]=1; //占领当前(i,j)所在的主对角线
           R_diagonal[i+j]=1; //占领当前(i,j)所在的副对角线
           if(i==8)
           {
              //print(); //此题没有要求输出
               sum++; //摆放种数加1    
           }
           else
               dfs(i+1);
           col[j]=0; //回溯(i,j)所在的列
           L_diagonal[i-j+7]=0; //回溯当前(i,j)所在的主对角线
           R_diagonal[i+j]=0;//回溯当前(i,j)所在的副对角线    
       }
}
int main()
{
   dfs(1);
   cout<<sum<<endl;
   return 0;
}


    扫描二维码推送至手机访问。

    版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

    分享给朋友:
    返回列表

    上一篇:数的拆分(1)

    下一篇:八皇后2

    相关文章

    【题解】马拦过河卒

    【题解】马拦过河卒

    【题目描述】棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。...

    【题解】最大平方因子

    【题目描述】给定一个整数 n,请找出 n 的最大平方因子。所谓平方因子,就是一个 n 的因子,且是一个完全平方数。最大平方因子就是 n&nb...

    2021年市南区程序设计竞赛(小学组)

    1.建设病房(build.cpp)【题目描述】2020年1月23日下午,武汉市建设局紧急召集中建三局等单位举行专题会议,要求参照2003年抗击非典期间北京小汤山医院模式,在武汉职工疗养院建设火神山医院...

    【题解】愤怒的牛

    【题目描述】农夫 John 建造了一座很长的畜栏,它包括N(2<=N<100000)个隔间,这些小隔间依次编号为x1,x2,...xn(0<=xi<=1000000000)。但...

    【题解】黑色联通块

    【题解】黑色联通块

    【题目描述】输入一个n×n的黑白图像(1表示黑色,0表示白色),任务是统计其中黑色连通块的个数。如果两个黑格子有公共边或者公共顶点,就说它们属于同一个联通块。如下图所示的图形有3个联通块。【输入描述】...

    【题解】智力大冲浪

    【题目描述】小伟报名参加中央电视台的智力大冲浪节目。本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者m元。先不要太高兴!因为这些钱还不一定都是你的。接下来主持人宣布了比赛规则:首...