问题描述:
在n*n的放个棋盘上放置n个皇后棋子,要求每个皇后要不同行、不同列、不同对角线。
求解:
根据他的要求,首先是不同行,那么就是一行最多只能有一个皇后,这个条件可以作为递归的参数。
其次,不同列好判断,遍历已经放置皇后的格子的y值与当前的y值不等即可。
关键在于不同对角线,画个图好理解,假设我们要放置的点为(3,3)。
以上为(3,3)部分对角线的元素,我们观察坐标可以发现这样一个关系。
(3,3)所有对角线的元素(i,j),|3-i|总是等于|3-j|,即构成一个等腰直角三角成。
如上,所有判断条件得到解决,现在设计递归。
递归需要一个二维数组为棋盘,n为棋盘边长,i为当前递归到的行数。
函数dis用于输出棋盘,place用于判断当前(i,j)可否放皇后。
完整代码:
#include<stdio.h>
#include<iostream>
using namespace std;
#define max 5
void dis(int chess[max][max],int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
cout << chess[i][j] << " ";
cout << endl;
}
cout << endl;
}
bool place(int chess[max][max],int n, int x, int y) {
if (x == 0)
return true;
else {
for (int i = 0; i < x; i++) {
for (int j = 0; j < n; j++) {
if (chess[i][j] == 1) {
if (j == y || abs(i - x) == abs(j - y))
return false;
}
}
}
}
return true;
}
void queen(int chess[max][max],int n,int i) {
if (i == n)
dis(chess, n);
for (int j = 0; j < n; j++) {
if (place(chess, n, i, j)) {
chess[i][j] = 1;
queen(chess, n, i + 1);
chess[i][j] = 0;
}
}
}
int main() {
int chess[max][max];
memset(chess, 0, sizeof(chess));
queen(chess, max, 0);
return 0;
}