八皇后问题

来源:互联网 发布:淘宝申请信用卡成功率 编辑:程序博客网 时间:2024/06/07 02:53

字符串全排列扩展----八皇后问题

本篇博客的描述部分得益于http://blog.csdn.net/hackbuteer1/article/details/7462447  代码和原文有很大不同
    题目:在8×8的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后不得处在同一行、同一列或者同一对角斜线上。下图中的每个黑色格子表示一个皇后,这就是一种符合条件的摆放方法。请求出总共有多少种摆法。


    这就是有名的八皇后问题。解决这个问题通常需要用递归,而递归对编程能力的要求比较高。因此有不少面试官青睐这个题目,用来考察应聘者的分析复杂问题的能力以及编程的能力。

由于八个皇后的任意两个不能处在同一行,那么这肯定是每一个皇后占据一行。于是我们可以定义一个数组ColumnIndex[8],数组中第i个数字表示位于第i行的皇后的列号。先把ColumnIndex的八个数字分别用0-7初始化,接下来我们要做的事情就是对数组ColumnIndex做全排列。由于我们是用不同的数字初始化数组中的数字,因此任意两个皇后肯定不同列。我们只需要判断得到的每一个排列对应的八个皇后是不是在同一对角斜线上,也就是数组的两个下标i和j,是不是i-j==ColumnIndex[i]-Column[j]或者j-i==ColumnIndex[i]-ColumnIndex[j]。

关于排列的详细讨论,详见上面的讲解。
接下来就是写代码了。思路想清楚之后,编码并不是很难的事情。下面是一段参考代码:



#include<iostream>  
using namespace std; 
void Permutation(int ColumnIndex[] , int length , int index);//递归得到全排列并且对全排列进行筛选
bool check(int ColumnIndex[]);
void printChess(int ColumnIndex[])
{
cout<<"this is a case"<<endl;
for(int i=0;i<8;i++)
{
for(int temp=0;temp<ColumnIndex[i]-1;temp++)
{
cout<<"  ";
}
cout<<"■ ";
for(int temp=0;temp<8-ColumnIndex[i];temp++)
{
cout<<"  ";
}
cout<<endl;
}

}
int main()
{
int ColumnIndex[8]={1,2,3,4,5,6,7,8};//初始化八个皇后在八个不同行的第1~8列 比如第ColumnIndex[2]=4 代表第2行的皇后在第4列
Permutation(ColumnIndex,0,7);
return 0;
}
bool check(int ColumnIndex[])//如果成功 返回1  失败 返回0
{
for(int i=0;i<8;i++)
{
for(int j=i+1;j<8;j++)
{
if((i-j==ColumnIndex[i]-ColumnIndex[j] )|| (j-i==ColumnIndex[i]-ColumnIndex[j]))
{
return 0;
}
}
    }
return 1;
}
void Permutation(int ColumnIndex[] , int from , int to)  //递归得到全排列并且对全排列进行筛选
{
if(to<=1)
{

return;

}
if(from==to)//输出和判断都在这里做
{
if(check(ColumnIndex))
{
    printChess(ColumnIndex);
}
}
else
{
for(int i=from;i<=to;i++)
{
swap(ColumnIndex[i],ColumnIndex[from]);
Permutation(ColumnIndex,from+1,to);
swap(ColumnIndex[i],ColumnIndex[from]);
}
}


}
0 0
原创粉丝点击