openjudge1700八皇后问题题解

八皇后问题

​​​​​​​

描述

在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方。

输入

无输入。

输出

按给定顺序和格式输出所有八皇后问题的解(见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 函数中,使用一个循环遍历当前行的每个位置。对于每个位置,判断是否可以放置皇后:

  • 如果当前位置没有放置皇后,并且当前位置所在的列、正对角线和反对角线上都没有其他皇后,那么可以放置皇后。
  • 在放置皇后后,将相应的标记数组 lxl1xl2 设为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;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值