n皇后问题:
在一个N*N的棋盘上摆放N个皇后,要求要求任意两个皇后不能冲突,即任意两个皇后不在同一行、同一列或者同一斜线上。例如,当N=4时,只有两种摆法。
一:
二:
递归求解复杂度太高,在此,使用回溯法。
即,我们在递归时,可以提前判断摆放是否满足条件,若不满足,返回上一层操作。在此,当我们递归的时候,判断当前皇后是否与前面的皇后在一条直线上,若在,结束递归,返回上一层;若不在,继续递归,进行判断。
代码
#include <stdio.h>
#include <malloc.h>
#include <math.h>
#include<stdbool.h>
int count=0;//存放解的个数
bool place(int* paraSolution, int paraT)//判断该位置是否满足条件
{
int j;
for (j = 1; j < paraT; j ++)
{
if ((abs(paraT - j) == abs(paraSolution[j] - paraSolution[paraT])) || (paraSolution[j] == paraSolution[paraT]))
{
return false;
}
}
return true;
}
void backtracking(int* paraSolution, int paraN, int paraT)
{
int n=0;
int i;
if (paraT > paraN)
{
for (i = 1; i <= paraN; i ++)
{
printf("%d ", paraSolution[i]);
n++;
if(n%paraN==0)
{
count++;
}
}
printf("\r\n");
}
else
{
for (i = 1; i <= paraN; i ++)
{
paraSolution[paraT] = i;
if(place(paraSolution, paraT))
{
backtracking(paraSolution, paraN, paraT + 1);
}
}
}
}
void nQueen(int paraN)
{
int i;
int* solution = (int*)malloc((paraN + 1) * sizeof(int));
for(i = 0; i <= paraN; i ++)
{
solution[i] = 0;
}
backtracking(solution, paraN, 1);
}
int main()
{
nQueen(6);
printf("\n解的个数为:%d",count);
return 1;
}