Description
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
Sample Input
1 8 5 0
Sample Output
1 92 10
问题很经典,和四色问题一样典型的深搜,要注意的的是判断条件,一开始我使用二维数组去存储皇后的位置果不其然,超时了。用二维数组将每一个皇后放下后影响的位置标记下来,在回朔的时候清除,这样思路确实简单,不过显得很是呆板,并且也不能过,其实可以用一个一位数组存储皇后的列坐标就可以了,因为皇后的横坐标肯定是递增的(假如你用的递归式的深搜的话),然后在放下一个皇后的时候在判断有么有哦重复就是。用一个for循环直到没有影响为止,否则返回。
代码如下:
#include<iostream>
using namespace std;
int num = 0;
int N;
int markArray[11] = { 0 };//存储皇后列坐标的数组
using namespace std;
int num = 0;
int N;
int markArray[11] = { 0 };//存储皇后列坐标的数组
void find(int k) {
bool flag; int i; int j;
if (k == 1 + N) { num++; return; }
else {
for (i = 1; i <= N; ++i)
{
markArray[k] = i;
flag = true;
for (j = 1; j < k; ++j)
{
if (i == markArray[j] || k - j == i - markArray[j] || k - j == markArray[j] - i)//这里就是判断是否在·一条竖线上,以及是否在一条斜线上,如果在一条斜线上,那么两个皇后的坐标..//形成的直线斜率为1或者-1
{
flag = false;
break;
}
}
if (flag) {
find(k + 1);
}
}
}
}
bool flag; int i; int j;
if (k == 1 + N) { num++; return; }
else {
for (i = 1; i <= N; ++i)
{
markArray[k] = i;
flag = true;
for (j = 1; j < k; ++j)
{
if (i == markArray[j] || k - j == i - markArray[j] || k - j == markArray[j] - i)//这里就是判断是否在·一条竖线上,以及是否在一条斜线上,如果在一条斜线上,那么两个皇后的坐标..//形成的直线斜率为1或者-1
{
flag = false;
break;
}
}
if (flag) {
find(k + 1);
}
}
}
}
int main() {
int as[11] = { 0 };
int m;
for (N = 1; N <= 10; ++N) {
num = 0;
find(1);
as[N] = num;
}
while (cin >> m&&m)
{
cout << as[m] << endl;
int as[11] = { 0 };
int m;
for (N = 1; N <= 10; ++N) {
num = 0;
find(1);
as[N] = num;
}
while (cin >> m&&m)
{
cout << as[m] << endl;
}
return 0;
}
}