以下为只输出结果的代码
include <cstdio>
#include <cstring>
#define N 10
using namespace std;
int vis[3][2*N];//分别标记列,主对角线,副对角线。注意对角线可能有2*n-1个,数组要开大点。
int n;
int cnt = 0;
void dfs(int cur)//cur表示当前行,i*i方阵
{
if (cur > n)//已放满皇后
{
cnt++;
return;
}
for (int i = 1; i <= n; i++)//i表示列
{
if (!vis[0][i] && !vis[1][cur + n - i] && !vis[2][cur + i])
{
vis[0][i] = vis[1][cur + n - i] = vis[2][cur + i] = 1;//标记所在列和所在主,副对角线
dfs(cur + 1);
vis[0][i] = vis[1][cur + n - i] = vis[2][cur + i] = 0;//回溯取消标记
}
}
}
int main()
{
int ans[N];
for (n = 1; n <= N; n++)//一共10种情况,先打表
{
cnt = 0;
memset(vis, 0, sizeof(vis));
dfs(1);
ans[n] = cnt;
}
while (scanf("%d", &n) != EOF && n)
printf("%d\n", ans[n]);
return 0;
}
以下可输出路径
#include <iostream>
#include <cmath>
#include <cstring>
#define N 11
using namespace std;
#include <cmath>
#include <cstring>
#define N 11
using namespace std;
int pos[N], n, sum;
void dfs(int step)
{
if (step == n)//摆放结束
{
sum++;
for (int i = 0; i < n; i++)
cout << pos[i] + 1 << ' ';
cout << endl;
return;
}
{
if (step == n)//摆放结束
{
sum++;
for (int i = 0; i < n; i++)
cout << pos[i] + 1 << ' ';
cout << endl;
return;
}
for (int i = 0; i < n; i++)//从第0列到第n-1列逐个尝试皇后所在位置
{
int j;
for (j = 0; j < step; j++)//和已经摆好的皇后进行比较看是否有冲突,j为行标,pos[j]为列标
{
if (pos[j] == i || abs(step - j) == abs(pos[j] - i))
break;//直接判断下一个
}
if (j == step)//说明无冲突
{
pos[step] = i;
dfs(step + 1);
}
}
}
{
int j;
for (j = 0; j < step; j++)//和已经摆好的皇后进行比较看是否有冲突,j为行标,pos[j]为列标
{
if (pos[j] == i || abs(step - j) == abs(pos[j] - i))
break;//直接判断下一个
}
if (j == step)//说明无冲突
{
pos[step] = i;
dfs(step + 1);
}
}
}
int main()
{
while (cin >> n && n)
{
sum = 0;
memset(pos, 0, sizeof(pos));
dfs(0);//从第0行开始摆放
cout << "一共有" << sum << "种摆法" << endl;
}
return 0;
}
{
while (cin >> n && n)
{
sum = 0;
memset(pos, 0, sizeof(pos));
dfs(0);//从第0行开始摆放
cout << "一共有" << sum << "种摆法" << endl;
}
return 0;
}