八皇后问题
描述
在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方。
输入
无输入。
输出
按给定顺序和格式输出所有八皇后问题的解(见Sample Output)。
样例输入
样例输出
No. 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 No. 2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 No. 3 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 No. 4 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 No. 5 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 No. 6 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 No. 7 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 No. 8 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 No. 9 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 ...以下省略
思路
1. 全局变量定义部分
int l[20], a[20][20], sum = 0, xl2[3000], xl1[2000], n;
这部分代码定义了一些全局变量:
l[20]
:用于记录每一行是否放置了皇后,l[i]
为1表示第i行已经放置了皇后。a[20][20]
:表示棋盘,a[i][j]
为1表示第i行第j列有一个皇后。sum
:用于计算总共的解的数量。xl2[3000]
、xl1[2000]
:用于记录每个对角线上是否已经放置了皇后。n
:表示棋盘的大小。
2. 递归函数 fx
的定义部分
int fx(int x) {
// ...
}
这部分代码定义了一个递归函数 fx
,用来处理每一行的皇后放置操作。函数的参数 x
表示当前要处理的行数。
3. 递归函数 fx
的具体实现部分
for (int i = 1; i <= n; i++) {
if (l[i] == 0 && xl1[i + x] == 0 && xl2[i - x + 100] == 0) {
// ...
}
}
这部分代码是 fx
函数的具体实现。在 fx
函数中,使用一个循环遍历当前行的每个位置。对于每个位置,判断是否可以放置皇后:
- 如果当前位置没有放置皇后,并且当前位置所在的列、正对角线和反对角线上都没有其他皇后,那么可以放置皇后。
- 在放置皇后后,将相应的标记数组
l
、xl1
、xl2
设为1,表示该行、列、对角线上已经有皇后。 - 然后,递归调用下一行,即
fx(x - 1)
。 - 如果当前行是最后一行(即
x == 1
),表示找到了一组解,将解的数量sum
加1,并输出当前解的棋盘布局。 - 最后,还原当前位置的标记,以便进行下一次尝试。
4. 主函数 main
的实现部分
int main() {
cin >> n;
fx(n);
cout << sum;
return 0;
}
这部分代码是主函数 main
的实现。首先从输入读入棋盘大小 n
,然后调用 fx(n)
函数,开始求解八皇后问题。最后输出解的数量 sum
。
将这些代码相结合,代码就实现了,AC代码如下:
#include<bits/stdc++.h>
using namespace std;
int l[20],a[20][20],sum=0,xl2[3000],xl1[2000],n;
int fx (int x)
{
for(int i=1;i<=n;i++)
{
if(l[i]==0&&xl1[i+x]==0&&xl2[i-x+100]==0)
{
a[i][x]=1;l[i]=1;xl1[i+x]=1;xl2[i-x+100]=1;
if (x>=2) fx(x-1);
else if (x==1){
sum++;
cout<<"No. "<<sum<<endl;
for(int j=1;j<=n;j++)
{
for(int k=n;k>=1;k--) cout<<a[j][k]<<" ";
cout<<endl;
}
}
a[i][x]=0;l[i]=0;xl1[i+x]=0;xl2[i-x+100]=0;
}
}
return 0;
}
int main()
{
cin>>n;
fx(n);
cout<<sum;
return 0;
}