/*
* 回溯法解N皇后问题
* 使用一个一维数组表示皇后的位置
* 其中数组的下标表示皇后所在的行
* 数组元素的值表示皇后所在的列
* 这样设计的棋盘,所有皇后必定不在同一行
*
* 假设前n-1行的皇后已经按照规则排列好
* 那么可以使用回溯法逐个试出第n行皇后的合法位置
* 所有皇后的初始位置都是第0列
* 那么逐个尝试就是从0试到N-1
* 如果达到N,仍未找到合法位置
* 那么就置当前行的皇后的位置为初始位置0
* 然后回退一行,且该行的皇后的位置加1,继续尝试
* 如果目前处于第0行,还要再回退,说明此问题已再无解
*
* 如果当前行的皇后的位置还是在0到N-1的合法范围内
* 那么首先要判断该行的皇后是否与前几行的皇后互相冲突
* 如果冲突,该行的皇后的位置加1,继续尝试
* 如果不冲突,判断下一行的皇后
* 如果已经是最后一行,说明已经找到一个解,输出这个解
* 然后最后一行的皇后的位置加1,继续尝试下一个解
*/
/*
* 检查第n行的皇后与前n-1行的皇后是否有冲突
* 发生冲突的充分必要条件是:
* a) 两皇后处于同一列,即a[i] == a[n]
* b) 两皇后处于同一斜线,即|a[i] - a[n]| == |i - n| == n - i
*
* bool conflict(int k)
* {
* int i;
* for(i=1;i<k;i++)
* if(x[k]==x[i]||abs(k-i)==abs(x[k]-x[i]))
* return true;
* return false;
* }
*/
#include<iostream.h>
#include<math.h>
int x[100];
bool conflict(int k)
{
int i;
for(i=1;i<k;i++)
if(x[k]==x[i]||abs(k-i)==abs(x[k]-x[i]))
return true;
return false;
}
int queen(int n)
{
int i,k;
int count=0;
for(i=1;i<=n;i++) //初始化棋盘
x[i]=0;
k = 1;
while(k>=1)
{
x[k]++;
while(x[k]<=n&&conflict(k))
x[k]++;
if(x[k]<=n&&k==n) //将符合条件的情况输出
{
for(i=1;i<=n;i++)
cout<<x[i]<<" ";
cout<<endl;
count++;
}
else if(x[k]<=n&&k<n)
k++;
else //如果达到N,仍未找到合法位置 ,那么就置当前行的皇后的位置为初始位置0 ,并回退上一行
{
x[k]=0;
k--;
}
}
return count;
}
void main()
{
int n;
cout<<"请输入皇后个数:";
cin>>n;
int count=queen(n);
cout<<count<<endl;
}