1.八皇后解决的两个主要步骤
1.如何确定某一行,某一列,主对角线方向,副对角线方向,是 否会发生冲突。
以该图为例
1.1主对角线
i-j=常数; 当常数相等时,在同一主对角线方向上;为使常数为正,统一加一个数(N-1)
1.2副对角线
i+j=常数; 当常数相等时,在同一主对角线方向上 ;
1.3行数
i与当前相等时就表示在同一行上;
2.回溯算法
具体见回溯法,代码中也有;
2.代码实现
#include<iostream>
using namespace std;
int map[15][15];
bool vis[15][15];
int N,ans=0;//Cow[j]标记列是否被使用;
bool Cow[20] , zhu[20] , xie[20];//分别来标记行,主对角线方向,副对角线方向是否被填充过
/*打印函数*/
void print()
{
for(int i=1; i<N; i++)
{
for(int j=1; j<=N; j++)
{
if(vis[i][j])
cout<<j<<" ";
}
}
for(int j=1; j<=N; j++)
{
if(vis[N][j])
cout<<j;
}
cout<<endl;
return ;
}
/*核心代码*/
void DFS(int i)
{
if(i==N+1)
{
if(ans<=2)//答案要求只打印前三种解
print();
ans++;
return ;
}
for(int j=1; j<=N; j++)//尝试放到第i行的每一列
{
if(!vis[i][j] && !Cow[j] && !zhu[i+j] && !xie[i-j+N-1])
{
vis[i][j]=true;Cow[j]=true; zhu[i+j]=true;xie[i-j+N-1]=true;//标记
DFS(i+1);
vis[i][j]=false;Cow[j]=false; zhu[i+j]=false;xie[i-j+N-1]=false;//回溯
}
}
return ;
}
int main()
{
cin>>N;
DFS(1);//代表放到第几行了,下标都从0开始;
cout<<ans; //ans代表有多少种方式
return 0;
}