在n×n的国际棋盘上放置n个皇后,使得每个皇后都不受到攻击,即任意二个皇后不能位于同行或同列或同一条斜线上。解题思路:将棋盘从左至右,从上到下编号为0,...,n-1,皇后编号为0,...,n-1。设解为(x0,..., xn-1) , 皇后i放在棋盘的第i行的第xi列上。
约束条件为:
- xi≠xj(不在一列上)
- xi-i≠xj-j(不在一条斜线上)
- xi+i≠xj+j(不在一条斜线上)
2)和3)等价于:|i-j|≠|xi-xj|
采用回溯算法思想,解决n个皇后问题的代码如下所示,请补充函数Place()的代码,要求输出n-皇后的所有可行解,输出列号(0~n-1)
函数接口定义:
bool place(int k, int i, int *x){ }
其中 k
、 i
和 *x
都是用户传入的参数。
裁判测试程序样例:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <cstring>
using std::cin;
using std::cout;
using std::endl;
int n; //皇后个数
bool place(int k, int i, int *x);
void nQueens(int k, int n, int *x);
int main()
{
cin>>n;
int *x = new int [n + 1];
if(n == 2 || n==3)
cout << "0" <<endl;
nQueens(0, n, x);
return 0;
}
/* 请在这里填写答案 */
void nQueens(int k, int n, int *x)
{
for(int i = 0; i < n; i++)
{
if(place(k, i, x))
{
x[k] = i;
if(k == n - 1)
{
for(i = 0; i < n; i++) cout << x[i] << " ";
cout << endl;
}
else
nQueens(k+1, n, x);
}
}
}
输入样例:
4
输出样例:
1 3 0 2
2 0 3 1
参考代码:
// 定义一个名为place的函数,接收三个参数:整数k、整数i和一个整数指针x
bool place(int k, int i, int* x) {
// 使用for循环遍历0到k-1的整数j
for (int j = 0; j < k; j++) {
// 如果x[j]等于i,说明在同一行或同一列存在相同的数字,返回false
if (x[j] == i) {
return false;
}
// 如果k和j的差的绝对值等于i和x[j]的差的绝对值,说明在同一对角线上存在相同的数字,返回false
else if (abs(k - j) == abs(i - x[j])) {
return false;
}
}
// 如果上述条件都不满足,说明可以放置数字i,返回true
return true;
}