【例1】八皇后问题。

在一个8×8国际象棋盘上,放置8个皇后,每个皇后占一格,要求皇后间不会出现相互“攻击”的现象,即不能有两个皇后处在同一行、同一列或同一对角线上。问共有多少种不同的放置方法?

(1)编程思路。

在八皇后问题中,由于任意两个皇后不同行,因此可以将布局表示为一维数组chess[8]。数组的下标i表示棋盘上的第i行,chess[i]的值表示皇后在第i行所放的位置。如chess[1]=5,表示在棋盘的第1行的第5列放一个皇后。

为了寻找满足要求的布局chess,可依次产生部分布局(chess[0]),(chess[0]、chess[1]),…,直至最后产生出完整布局(chess[0]、chess[1]、…、chess[7])。每一步都要求保证它们是在不同列和不同对角线上。可采用深度优先搜索算法完成。

(2)源程序。

#include <iostream>

using namespace std;

void show_chess(void);

int check(int n);

void putchess(int n);

int chess[8];

int main()

{

cout<<"All Results are :"<<endl;

putchess(0);

return 0;

}

// 递归函数:在从第n行开始放皇后

void putchess(int n)

{

int i;

if (n<8)

{

for (i = 0; i <8; i++)      // 将第n行从第一格(i)开始往下放

{

chess[n] = i;

if (check(n) == 1)       // 若可放,则检查是否放满

{

if (n == 7)

show_chess();     // 若已放满到8行时,则表示找出一种解,打印出来

else

putchess(n + 1);   // 若没放满则放下一行 putchess(n+1)

}

}

}

}

// 根据前面几行的子,检查第n行所放的皇后是否合法

int check(int n)

{

int i;

for (i = 0; i <= n - 1; i++)

if (chess[n] == chess[i] + (n - i) ||chess[n] == chess[i] - (n - i) ||chess[n] == chess[i] )

return 0;

return 1;

}

// 函数:打印结果

void show_chess(void)

{

static int count = 0;

cout<<"************* 第"<<++count<<"种 *************"<<endl;

for(int i=0; i<8; i++)

{

for(int j=0; j<8; j++)

if (j==chess[i]) cout<<"1 ";

else  cout<<"0 ";

cout<<endl;

}

}

【例2】棋盘问题(POJ 1321)。
Description

在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
Input

输入含有多组测试数据。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
Output

对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
Sample Input

2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1
Sample Output

2
1

(1)编程思路。

在棋盘问题中,棋子摆放的位置只能是“#”, 且不能同行和同列。由于在深度优先搜索中采用按行递增的顺序来搜索的,这样每次递归下一行,所以每一行不会有冲突,不可能出现同行的情况。只需保证不同列,为判断某一列上是否有其他棋子,可定义一个数组visit[]来保存列的访问状态,visit[i]=true表示第i列上放置有棋子;visit[i]=false表示第i列上未放置棋子。

(2)源程序1。

#include <iostream>

using namespace std;

bool visit[20];

char map[20][20];

int ans,k,n;    // ans表示方案数,k表示棋子数目,n表示棋盘的大小

void DFS(int row,int num)   // 逐行搜索,row为当前搜索行,num为已填充的棋子数

{

if(num>=k)   // 判断是否棋子已经放完,如果放完,记录方案数加1

{

ans++;

return;

}

for(int i=row;i<n;i++)

{

for(int j=0;j<n;j++)

{

if(!visit[j] && map[i][j]=='#')  // 如果该列没放棋子且该位置为棋盘,那么在这里放上棋子

{

visit[j]=true;             // 标记该列上有棋子

DFS(i+1,num+1);   // 搜索下一行放下一个棋子

visit[j]=false;           // 修改标记后递归回来要及时复原

}

}

}

}

int main()

{

int i;

while (cin>>n>>k)

{

if (n==-1&&k==-1)

break;

for (i=0;i<n;i++)

visit[i]=false;

for (i=0;i<n;i++)

cin>>map[i];

ans=0;

DFS(0,0);

cout<<ans<<endl;

}

return 0;

}

(3)源程序2。

#include <iostream>
using namespace std;
bool visit[20];
char map[20][20];
int ans,k,n;   // ans表示方案数,k表示棋子数目,n表示棋盘的大小
void DFS(int row,int num)    // 逐行搜索,row为当前搜索行,num为已填充的棋子数
{
    if(num==k)
   {
       ans++;
       return;
    }
    if (row>=n) return ;
    for(int j=0;j<n;j++) // 当前行放一个棋子
    {
        if(!visit[j] && map[row][j]=='#')
       {
           visit[j]=true;
           DFS(row+1,num+1);
           visit[j]=false;
        } 
     }
    DFS(row+1,num); // 当前行不放棋子
}
int main()
{
     int i;
     while (cin>>n>>k)
     {
         if (n==-1&&k==-1)
             break;
         for (i=0;i<n;i++)
             visit[i]=false;
         for (i=0;i<n;i++)
             cin>>map[i];
         ans=0;
        DFS(0,0);
        cout<<ans<<endl;
    }
    return 0;
}

DFS(三):八皇后问题的更多相关文章

  1. 用dfs求解八皇后问题

    相信大家都已经很熟悉八皇后问题了,就是指:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法.主要思路:按行进行深度优先搜索,在该 ...

  2. hdu2553N皇后问题(dfs,八皇后)

    N皇后问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  3. dfs 解决八皇后问题 以及其他图搜索问题

    33. N皇后问题 中文 English n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击(任意两个皇后不能位于同一行,同一列,同一斜线). 给定一个整数n,返回所有不同的n皇后问 ...

  4. DFS解决八皇后问题

    2019-07-29 16:49:15 #include <bits/stdc++.h> using namespace std; ][]; int tot; int check(int ...

  5. 洛谷 P1219 八皇后【经典DFS,温习搜索】

    P1219 八皇后 题目描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 上面的布局可以用序 ...

  6. 深度搜索(dfs)+典型例题(八皇后)

    深度优先搜索简称深搜,从起点出发,走过的点要做标记,发现有没走过的点,就随意挑一个往前走,走不了就回退,此种路径搜索策略就称为“深度优先搜索”,简称“深搜”. 如上面的图所示:加入我们要找一个从V0到 ...

  7. 八皇后(dfs+回溯)

    重看了一下刘汝佳的白板书,上次写八皇后时并不是很懂,再写一次: 方法1:逐行放置皇后,然后递归: 代码: #include <bits/stdc++.h> #define MAXN 8 # ...

  8. 八皇后问题-dfs

    一.题意解析 国际象棋中的皇后,可以横向.纵向.斜向移动.如何在一个8X8的棋盘上放置8个皇后,使得任意两个皇后都不在同一条横线.竖线.斜线方向上?八皇后问题是一个古老的问题,于1848年由一位国际象 ...

  9. 八皇后问题解题报告(dfs

    这里是代码传送门 所谓八皇后问题,一开始接触,上学期舍友提及的,但是因为各种原因,水平不够,并没有关心,偶然之间,再次遇见,便进行的尝试(棋盘是0-7的,不是1-8的...开始打弄错了) 所谓八皇后问 ...

随机推荐

  1. Sql ----- sqlserver 中的if 判断 case... when

    与查询放到一块使用: 语法: select case when 范围条件 then 产生的结果 when 范围条件 then 产生的结果 else 不是以上范围产生的结果 end from 表名 个人 ...

  2. 安全性测试:OWASP ZAP 2.8 使用指南(一):安全测试基础及ZAP下载、安装

    概览 本文意在对于OWASP's Zed Attack Proxy(ZAP)软件做一个基本使用指南介绍. ZAP是一个用于实施安全性测试的工具,即使没有很强的安全测试背景也可以很好的使用. 为了达到这 ...

  3. 2019_JAVA面试题_真实总结

    来自刚被某互联网公司录取的朋友的分享. 整理的面试题1: 1.Java里面有哪几种基础数据类型, 2.Char为何是两个字节, 3.Object有哪些方法 4.final修饰变量,函数,类的作用, 5 ...

  4. Java设计模式:Builder(构建器)模式

    概念定义 Builder模式是一步一步创建一个复杂对象的创建型模式.该模式将构建复杂对象的过程和它的部件解耦,使得构建过程和部件的表示隔离开来. 应用场景 对象创建过程比较复杂,或对创建顺序或组合有依 ...

  5. python3报'ascii' codec can't encode characters in position 0-7: ordinal not in range(128)解决方法

    运行前指定export PYTHONIOENCODING为utf-8 如 export PYTHONIOENCODING=utf-8; python main.;y

  6. sequelize时间自动格式化

    问题 每次查询datetime的字段,显示出来都是这种格式 2019-08-27T12:02:05.000Z 解决办法 初始化Sequelize的时候传入dialectOptions参数 let se ...

  7. JS基础语法---练习:交换两个变量的值

    * JavaScript简称为JS * JavaScript是什么?     * 是一门脚本语言:不需要编译,直接运行     * 是一门解释性的语言:遇到一样代码就解释一行代码     * C#语言 ...

  8. uni-app聊天室|vue+uniapp仿微信聊天实例|uniapp仿微信App界面

    一.介绍 运用UniApp+Vue+Vuex+swiper+uniPop等技术开发的仿微信原生App聊天室|仿微信聊天界面实例项目uniapp-chatroom,实现了发送图文消息.表情(gif图), ...

  9. QML::Rectangle组件

    QML的Rectangle组件,描绘一个矩形,一个可视化的对象. 外加设置属性来达到我们想要的效果.常用的有矩形的颜色,边框颜色,圆角等设置. Rectangle{ x:10//这里的坐标是相对于它的 ...

  10. Java --Lamda表达式

    Lamda:属于函数式编程的概念: interface IMessage { public void print() ; } public class TestDemo { public static ...