题目
最近在复习数据结构的栈这块时看到的书后习题,大一初学c那会儿一直觉得N皇后问题是个很难的问题,系统的学习完数据结构再来看这道题已经有了不一样的思考方向了。
此处不在赘述n皇后问题的具体内容,直接放源码
源码
#include<stdio.h>
#include<math.h>
#define N 12
int N_Queen(int n)
{
if (n <= 2)return -1;
int i, j, num = 0;
int s[100];
int top = -1, x;
int pass, pre, find;
s[++top] = 0;
while (top != -2)//不等于-2是由于回溯时第一行已经被遍历完,导致top指向-2(虽然不方便理解,但可以减少一次判断)
{
x = top; pre = -1;
if (x == N - 1)
{
num++;
pre = s[--top];
--top;
x = x - 2;
}
while (top!=-2)//回溯循环
{
find = 0;
for (j =pre+1; j < N; j++)
{
pass = 1;
for (i = top; i >= 0; i--)//筛选循环
{
if (j ==s[i] || abs(x + 1 - i) == abs(j - s[i]))
{
pass = 0;
break;//该列与任意一个栈内的合法皇后不满足条件,就进入下一列。
}
}
if (pass)//x+1行找到一个合法皇后
{
s[++top]=j; //将其入栈
find = 1;
break;
}
}
if (!find)//如果x+1一整行没有找到合法皇后
{
pre = s[top--];//回溯
x--;
}
else break;
}
}
return num;
}
int main()
{
printf("%d\n",N_Queen(N));
}
其他
其实还有一些比较容易实现的优化,比如n皇后问题的解是左右对称的,因此我们只需要针对偶数n和奇数n设定好终止位置,将已知解的个数通过公式计算出来即可(比如偶数n皇后问题只需要求出左半边的所有解即可)