n皇后问题[分支限界法]
问题:
如何能够在 n×n 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。
分析:
我们可以用一串数字来表示问题的解,比如[2,4,1,3] 表示 4×4 棋盘的4皇后问题的解,第一行的棋子摆在第2列;第二行的棋子摆在第4列,依此类推
这里将用回溯法进行解题,可以看出,某一行的棋子摆了之后,棋子的那一列肯定不能再摆其他的棋子了,
所以解[x,x,x,……,x] 一定是 1-n 的一个全排列,
所以这里的解空间树我们选择排列树。
思路:
既然已经确定了要用排列树来作为问题的解空间树,接下来要确定的就是剪枝函数了。
剪枝函数只要从已经摆好的棋子的第一个开始遍历,依此判断下面的棋子是否在其攻击范围内即可,
因为我们之前没有在同一行摆多个棋子,也没有在同一列摆多个棋子,所以只要判断其他棋子是否在其斜线上的攻击范围即可,比如
第一行的棋子摆在第3列上,只要沿图中方向判断即可
for (int i = ; i <= n-; i++)
{
for (int j = i + ; j <= n; j++)
{
int left = -(j - i);//向左的斜线
int right = (j - i);//向右的斜线
if (pieces[j] == pieces[i] + left||pieces[j] == pieces[i] + right)
{//第i行皇后和第j行皇后会互相攻击
return false;
}
}
}
代码:
这样摆好所有棋子后即可输出,代码如下:
#include<iostream>
#include<ctime>
using namespace std; bool isOK(int n, int pieces[])
{ //剪枝函数
//判断当前状态是否合理,即皇后会不会互相攻击
for (int i = ; i <= n-; i++)
{
for (int j = i + ; j <= n; j++)
{
int left = -(j - i);//向左的斜线
int right = (j - i);//向右的斜线
if (pieces[j] == pieces[i] + left||pieces[j] == pieces[i] + right)
{//第i行皇后和第j行皇后会互相攻击
return false;
}
}
}
//所有皇后都不会互相攻击
return true;
} void swap(int &a, int &b)
{
int t = a;
a = b;
b = t;
} void nQueen(int n, int t, int pieces[])
{
if (t > n)
{
for (int i = ; i <= n; i++)
{
for (int j = ; j < pieces[i]; j++)
cout << "- ";
cout << pieces[i]<<" ";
for (int j = pieces[i] + ; j <= n; j++)
cout << "- ";
cout << endl;
}
cout << endl;
}
else
{
for (int i = t; i <= n; i++)
{
swap(pieces[t], pieces[i]);
if (isOK(t, pieces))
{
nQueen(n, t + , pieces);
}
swap(pieces[t], pieces[i]);
}
}
} void main()
{
int n;
cin >> n;
int *pieces = new int[n + ];
for (int i = ; i <= n; i++)
{
pieces[i] = i;
}
nQueen(n, , pieces);
cout << "OK" << endl;
system("pause");
}
n皇后问题[分支限界法]的更多相关文章
- ytu 1789:n皇后问题(水题,枚举)
n皇后问题 Time Limit: 1 Sec Memory Limit: 64 MB Special JudgeSubmit: 12 Solved: 3[Submit][Status][Web ...
- 1319-n皇后问题
描述 在n×n 格的棋盘上放置彼此不受攻击的n 个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.n后问题等价于在n×n格的棋盘上放置n个皇后,任何2 个皇后不放在同一 ...
- 递归实现n(经典的8皇后问题)皇后的问题
问题描述:八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后, 使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行.纵行或斜线上 ...
- 八皇后算法的另一种实现(c#版本)
八皇后: 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于 ...
- [LeetCode] N-Queens II N皇后问题之二
Follow up for N-Queens problem. Now, instead outputting board configurations, return the total numbe ...
- [LeetCode] N-Queens N皇后问题
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens ...
- N皇后问题—初级回溯
N皇后问题,最基础的回溯问题之一,题意简单N*N的正方形格子上放置N个皇后,任意两个皇后不能出现在同一条直线或者斜线上,求不同N对应的解. 提要:N>13时,数量庞大,初级回溯只能保证在N< ...
- 数据结构0103汉诺塔&八皇后
主要是从汉诺塔及八皇后问题体会递归算法. 汉诺塔: #include <stdio.h> void move(int n, char x,char y, char z){ if(1==n) ...
- N皇后问题
题目描述 在n×n格的棋盘上放置彼此不受攻击的n个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.n后问题等价于再n×n的棋盘上放置n个后,任何2个皇后不妨在同一行或同 ...
随机推荐
- C# for Hbase 实现详解
一共两种方式访问 通过Thrift访问 目前hbase src.tar.gz压缩包中包含thrift he thrift2; 根据官方文档,thrift可能被抛弃,但是网上基本上都是介绍thrift的 ...
- linux常用命令 查看文件
Linux常用命令 查看文件 cat命令 cat命令的用途是连接文件或标准打印输入并打印.这个命令常用来显示文件内容,或者将几个文件连接起来显示,或者从标准输入读取内容并显示. 命令格式: cat [ ...
- selenium TestNG基本注释和属性
TestNG注释详解 suite 属性说明: @name: suite 的名称,必须参数@junit:是否以Junit 模式运行,可选值(true | false),默认"false&quo ...
- Go语言map映射的基本操作
对比python, java都有对应的字典类型及哈希类型. package main import ( "fmt" ) //main is the entry of the pro ...
- IP自动切换脚本
@echo off & cls & color 47 & mode con cols=80 lines=25 & title [IP自动切换工具]clsecho. ec ...
- 拓扑排序(Topological Order)UVa10305 Ordering Tasks
2016/5/19 17:39:07 拓扑排序,是对有向无环图(Directed Acylic Graph , DAG )进行的一种操作,这种操作是将DAG中的所有顶点排成一个线性序列,使得图中的任意 ...
- 11.5NOIP2018提高组模拟题
书信(letter) Description 有 n 个小朋友, 编号为 1 到 n, 他们每人写了一封信, 放到了一个信箱里, 接下来每个人从中抽取一封书信. 显然, 这样一共有 n!种拿到书信的情 ...
- 区间DP【p4290】[HAOI2008]玩具取名
Description 某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后他会根据自己的喜好,将名字中任意一个字母用"WING"中 ...
- noi 题库1.7字符串 第16至20题
16:忽略大小写的字符串比较 一般我们用strcmp可比较两个字符串的大小,比较方法为对两个字符串从前往后逐个字符相比较(按ASCII码值大小比较),直到出现不同的字符或遇到'\0'为止.如果全部字符 ...
- sed 很棒的介绍
选项与参数:-n :使用安静(silent)模式.在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上.但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作) ...