实验1---N皇后问题
2014-06-09 22:13
197 查看
N皇后问题:n由键盘输入,当且仅当 n = 1 或 n ≥ 4 时问题有解。令一个一位数组queen
保存所得解,其中queen[i] 表示把第i个皇后放在第i行的列数(注意i的值都是从0开始计算的)一个简单的从规则到问题提取过程:
(1)因为所有的皇后都不能放在同一列,因此数组的不能存在相同的两个值。
(2)所有的皇后都不能在对角线上,那么该如何检测两个皇后是否在同一个对角线上?我们将棋盘的方格成一个二维数组,假设有两个皇后被放置在(i,j)和(k,l)的位置上,明显,当且仅当|i-k|=|j-l| 时,两个皇后才在同一条对角线上。
#include <iostream.h>
#include <stdlib.h>
int max; /* max为棋盘最大坐标 */
int *queen;
char **q;
int flag=0;
void init() /*初始化矩阵*/
{
for(int i=0; i<max; i++)
{
for(int j=0; j<max; j++)
{
q[i][j] = 'X';
}
}
}
void show() /* 输出所有皇后的坐标 */
{
int i;
init();
for(i = 0; i < max; i++)
{
q[i][queen[i]] = 'Q';
}
for(i=0; i<max; i++)
{
for(int j=0; j<max; j++)
{
cout<<q[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
int PLACE(int n) /* 检查当前列能否放置皇后 */
{
int i;
for(i = 0; i < n; i++) /* 检查横排和对角线上是否可以放置皇后 */
{
if(queen[i] == queen
|| abs(queen[i] - queen
) == (n - i))
{
return 1;
}
}
return 0;
}
void NQUEENS(int n) /* 回溯尝试皇后位置,n为横坐标 */
{
int i;
for(i = 0; i < max; i++)
{
queen
= i; /* 将皇后摆到当前循环到的位置 */
if(!PLACE(n))
{
if(n == max - 1 && flag<3)
{
show(); /* 如果全部摆好,则输出所有皇后的坐标 */
flag++;
}
else
{
NQUEENS(n + 1); /* 否则继续摆放下一个皇后 */
}
}
}
}
int main()
{
cout<<"请输入N:";
cin>>max;
queen = new int[max];
q = new char *[max];
for(int i=0; i<max; i++)
q[i] = new char [max];
NQUEENS(0); /* 从横坐标为0开始依次尝试 */
return 0;
}<pre name="code" class="cpp">
运行结果:
![](https://img-blog.csdn.net/20140609221243156?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY19teTIwMTE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](https://img-blog.csdn.net/20140609221308609?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY19teTIwMTE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
保存所得解,其中queen[i] 表示把第i个皇后放在第i行的列数(注意i的值都是从0开始计算的)一个简单的从规则到问题提取过程:
(1)因为所有的皇后都不能放在同一列,因此数组的不能存在相同的两个值。
(2)所有的皇后都不能在对角线上,那么该如何检测两个皇后是否在同一个对角线上?我们将棋盘的方格成一个二维数组,假设有两个皇后被放置在(i,j)和(k,l)的位置上,明显,当且仅当|i-k|=|j-l| 时,两个皇后才在同一条对角线上。
#include <iostream.h>
#include <stdlib.h>
int max; /* max为棋盘最大坐标 */
int *queen;
char **q;
int flag=0;
void init() /*初始化矩阵*/
{
for(int i=0; i<max; i++)
{
for(int j=0; j<max; j++)
{
q[i][j] = 'X';
}
}
}
void show() /* 输出所有皇后的坐标 */
{
int i;
init();
for(i = 0; i < max; i++)
{
q[i][queen[i]] = 'Q';
}
for(i=0; i<max; i++)
{
for(int j=0; j<max; j++)
{
cout<<q[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
int PLACE(int n) /* 检查当前列能否放置皇后 */
{
int i;
for(i = 0; i < n; i++) /* 检查横排和对角线上是否可以放置皇后 */
{
if(queen[i] == queen
|| abs(queen[i] - queen
) == (n - i))
{
return 1;
}
}
return 0;
}
void NQUEENS(int n) /* 回溯尝试皇后位置,n为横坐标 */
{
int i;
for(i = 0; i < max; i++)
{
queen
= i; /* 将皇后摆到当前循环到的位置 */
if(!PLACE(n))
{
if(n == max - 1 && flag<3)
{
show(); /* 如果全部摆好,则输出所有皇后的坐标 */
flag++;
}
else
{
NQUEENS(n + 1); /* 否则继续摆放下一个皇后 */
}
}
}
}
int main()
{
cout<<"请输入N:";
cin>>max;
queen = new int[max];
q = new char *[max];
for(int i=0; i<max; i++)
q[i] = new char [max];
NQUEENS(0); /* 从横坐标为0开始依次尝试 */
return 0;
}<pre name="code" class="cpp">
运行结果:
相关文章推荐
- 第1次实验——八皇后及N皇后问题
- 第一次实验:八皇后及N皇后问题
- 实验一 八皇后问题
- 实验1——N皇后问题的求可行解个数(回溯法)
- 第1次实验——NPC问题(回溯算法、聚类分析) N皇后的问题
- 算法分析与设计实验三 回溯法 24点问题 n皇后问题
- 第一次实验 八皇后及N皇后问题
- 第一次实验--八皇后及N皇后问题
- 第一次实验,8皇后问题算法
- 八皇后问题程序
- vb实现与单片机的通讯问题(转载,经实验,正确!!!)
- 关于N皇后问题高效试探回溯算法的分析
- 使用C#求解N皇后问题。
- 回溯法的一个经典实例-n皇后问题
- 回溯法求解8皇后问题(转帖)
- 国际象棋“皇后”问题的回溯算法
- 回溯法解决N皇后问题
- 自己对“一个C的实验及疑惑 ”一文中问题的解释!
- 8皇后问题
- 8皇后问题改进~