方法1:
用(i,C[i])记录皇后所在的位置,递归回溯(for),注意皇后不在同列和对角线上
tot记录方法数
#include <iostream>
#include <cmath>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#define maxn 100
using namespace std;
typedef long long ll;
int n,tot=0,C[maxn];
void search(int cur)//cur表示cur行
{
if(cur==n)
{
tot++;
for(int i=0;i<n;i++)
printf("%d ",C[i]);
printf("\n");
}
else
{
for(int i=0;i<n;i++)//每一列遍历
{
int ok=1;
C[cur]=i;
for(int j=0;j<cur;j++)//和之前已放好的比较,判断现在这个皇后放的位置是否合适
{
if(C[cur]==C[j]||abs(cur-j)==abs(C[cur]-C[j]))
{
ok=0;
break;
}
}
if(ok) search(cur+1);
}
}
}
int main()
{
cin>>n;
search(0);
cout<<tot<<endl;
return 0;
}
n=4时,输出:
1 3 0 2
2 0 3 1
2
方法2:
先判断当前cur行i列上是否可以放:同一列没有皇后&&主对角线上没有元素&&副对角线上没有元素
用二维数组vis[3][]做标记
vis[0][i]=1;第i列有皇后
注意:(cur,i)表示在方格中的位置
从左上到右下的对角线上的单元格,cur-i的值都是一样的,但有正有负
所以vis[2][cur-i+n]=1表示从左上到右下的对角线上存在皇后
从右上到左下的每条对角线的所有单元格的cur+i的值都相同
所以vis[1][cur+i]=1表示从右上到左下的对角线上有皇后
注意回溯!!
#include <iostream>
#include <cmath>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#define maxn 100
using namespace std;
typedef long long ll;
int n,tot=0,C[maxn],vis[3][maxn];
void search(int cur)//cur表示cur行
{
if(cur==n)
{
tot++;
for(int i=0;i<n;i++)
printf("%d ",C[i]);
printf("\n");
}
else
{
for(int i=0;i<n;i++)//对于一行的每一 列遍历
{
if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+n])
{
C[cur]=i;
vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1;
search(cur+1);
vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=0;//回溯,寻找其他可能的可行方案
}
}
}
}
int main()
{
cin>>n;
memset(vis,0, sizeof(vis));
search(0);
cout<<tot<<endl;
return 0;
}
n=4时的输出同上