DFS(三):八皇后问题
【例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(三):八皇后问题的更多相关文章
- 用dfs求解八皇后问题
相信大家都已经很熟悉八皇后问题了,就是指:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法.主要思路:按行进行深度优先搜索,在该 ...
- hdu2553N皇后问题(dfs,八皇后)
N皇后问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- dfs 解决八皇后问题 以及其他图搜索问题
33. N皇后问题 中文 English n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击(任意两个皇后不能位于同一行,同一列,同一斜线). 给定一个整数n,返回所有不同的n皇后问 ...
- DFS解决八皇后问题
2019-07-29 16:49:15 #include <bits/stdc++.h> using namespace std; ][]; int tot; int check(int ...
- 洛谷 P1219 八皇后【经典DFS,温习搜索】
P1219 八皇后 题目描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 上面的布局可以用序 ...
- 深度搜索(dfs)+典型例题(八皇后)
深度优先搜索简称深搜,从起点出发,走过的点要做标记,发现有没走过的点,就随意挑一个往前走,走不了就回退,此种路径搜索策略就称为“深度优先搜索”,简称“深搜”. 如上面的图所示:加入我们要找一个从V0到 ...
- 八皇后(dfs+回溯)
重看了一下刘汝佳的白板书,上次写八皇后时并不是很懂,再写一次: 方法1:逐行放置皇后,然后递归: 代码: #include <bits/stdc++.h> #define MAXN 8 # ...
- 八皇后问题-dfs
一.题意解析 国际象棋中的皇后,可以横向.纵向.斜向移动.如何在一个8X8的棋盘上放置8个皇后,使得任意两个皇后都不在同一条横线.竖线.斜线方向上?八皇后问题是一个古老的问题,于1848年由一位国际象 ...
- 八皇后问题解题报告(dfs
这里是代码传送门 所谓八皇后问题,一开始接触,上学期舍友提及的,但是因为各种原因,水平不够,并没有关心,偶然之间,再次遇见,便进行的尝试(棋盘是0-7的,不是1-8的...开始打弄错了) 所谓八皇后问 ...
随机推荐
- 打开Github网站反应慢的问题
解决办法: 为了提高速度,可以使用HOSTS加速对Github网站加载的资源网站域名解析. 具体做法: 修改 C:\Windows\System32\drivers\etc 中的hosts文件(P ...
- hibernate中的merge()方法
Hibernate提供有save().persist().savaOrUpdate()和merge()等方法来提供插入数据的功能.前三者理解起来较后者容易一些,而merge()方法从api中的介绍就可 ...
- 网上售卖几百一月的微信机器,Python几十行代码就能搞定
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 故事胶片 PS:如有需要Python学习资料的小伙伴可以加点击下方链 ...
- python验证码识别(2)极验滑动验证码识别
目录 一:极验滑动验证码简介 二:极验滑动验证码识别思路 三:极验验证码识别 一:极验滑动验证码简介 近些年来出现了一些新型验证码,不想旧的验证码对人类不友好,但是这种验证码对于代码来说识别难度上 ...
- Python-警告处理
python 下Warning的使用 起因是这样的,当我使用pymysql模块执行建表的sql语句时获,在控制台输出了红色的消息,但是程序并没有终止而是继续运行了 sql语句如下: CREATE TA ...
- Vue入门、插件安装
一.Vue 1.什么是Vue? (1)官网地址: https://cn.vuejs.org/ (2)Vue是一个渐进式的JavaScript框架.采用自底向上增量开发的设计.可以简单的理解为Vue是一 ...
- VUE组内培训
最近去参加了一个外部VUE的周末培训,加上自己比较感兴趣所以对这项很热的前端框架做了点学习,顺便给组内同事做个简单的分享,希望下次有项目可以使用上- VUE的语法教程网上很多我就不一一列举,截图放一下 ...
- 从0系统学Android-1.4日志工具的使用
更多精品文章分类 1.4 日志工具 简单介绍一下日志工具,对以后的开发非常有用 1.4.1 使用日志工具 Log Log 日志工具类提供了 5 个方法来供我们打印信息(级别逐渐提高) Log.v(): ...
- CODING 签约天津大学,助力高校“产学”接轨
近日,CODING 与天津大学顺利达成合作,将通过 CODING 的一站式 DevOps 解决方案为天津大学师生提供软件研发管理方面的先进理念和产品. 根据中共中央.国务院印发的<中国教育现代化 ...
- 9.JavaCC官方入门指南-例4
例4:计算器--添加减法运算 1. calculator1.jj 为了使得计算器具备更多功能,我们需要更多的操作符,比如减法.乘法和除法.接下来我们添加减法运算. 在词法分析器的描述部分,我们 ...