题目:在8×8 的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后不得处在同一行、同一列或者同一对角斜线上。下图中的每个黑色格子表示一个皇后,这就是一种符合条件的摆放方法。请求出总共有多少种摆法。
我的思路很简单,就是把8皇后看成是一个8*8的矩阵,初始化的值为0,核心思想是递归。
1、第一行定了一个皇后,把这个皇后的列,两边斜对角value+1;
2、①从第二行开始把value为0的格子定为皇后(依次遍历)②把皇后的从下一行开始的列,两斜对角value+1;
3、如果某一行的格子全部不为0,则返回上一层递归,同时执行2中②的value-1操作。
代码(编译可执行):
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <iostream>
#include <unistd.h>
const int QueenValue=8;
using namespace std;
void SetQueenValue(int **arry,int row,int column,int value)
{
int rRow=row;
int lRow=row;
int lColumn=column-1;
int rColumn=column+1;
for(unsigned int i=row;i<QueenValue;++i)
{
arry[i][column]+=value;
if(rRow<=QueenValue-1&&rColumn<=QueenValue-1)
{
arry[rRow][rColumn]+=value;
++rRow;
++rColumn;
}
if(lRow<=QueenValue-1&&lColumn>=0)
{
arry[lRow][lColumn]+=value;
++lRow;
--lColumn;
}
}
return;
}
void printpath(vector<pair<int,int> > QueenWays)
{
if(QueenWays.size()!=QueenValue)
return;
for(vector<pair<int,int> >::iterator it=QueenWays.begin();it!=QueenWays.end();++it)
{
// cout<<it->first<<" "<<it->second<<endl;
for(unsigned int i=0;i<QueenValue;++i)
{
if(i==it->second)
cout<<"1";
cout<<"0";
}
cout<<endl;
}
cout<<endl;
sleep(10);
return;
}
void IsQueen(int **arry,int &total,vector<pair<int,int> >&QueenWays,int row)
{
if(QueenWays.size()!=row)
return;
if(row>=QueenValue)
{
total+=1;
printpath(QueenWays);
return;
}
for(unsigned int i=0;i<QueenValue;++i)
{
if(arry[row][i]==0){
QueenWays.push_back(make_pair(row,i));
SetQueenValue(arry,row+1,i,1);
IsQueen(arry,total,QueenWays,row+1);
QueenWays.pop_back();
SetQueenValue(arry,row+1,i,-1);
}
}
return;
}
int GetDequeOfQueen()
{
int **arry=new int* [QueenValue];
for(unsigned int i=0;i<QueenValue;++i)
arry[i]=new int[QueenValue];
// memset(arry,0,sizeof(arry));
cout<<arry[0][0]<<endl;
int total=0;
vector<pair<int,int> > QueenWays;
IsQueen(arry,total,QueenWays,0);
return total;
}
int main()
{
cout<<GetDequeOfQueen()<<endl;
return 0;
}