C - N皇后问题
在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
Input
共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。
Output
共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。
Sample Input
1
8
5
0
Sample Output
1
92
10
#include <stdio.h>
#include <string.h>
int getMethod(const int n);
int checkPoint(int *column,const int n);
int main()
{
const int MAX=10;//说明N最大为10
const int END=0;//说明输入0表示程序结束
int N;
while (scanf("%d",&N))
{
if (N>MAX || N<0)
{
return -1;
}
else if (N==END)
{
return 0;
}
int method=getMethod(N);
printf("%d",method);
printf("\n");
}
return 0;
}
int getMethod(const int n)
{
int column[n+1];
// column[1]~column[n]存储n个皇后的纵坐标,其下标表示皇后的横坐标,column[0]存储皇后的总共摆法
memset(column, 0, (n+1)*sizeof(int));//column数组置零
int method=checkPoint(column,n);//返回总共的摆法
return method;
}
int checkPoint(int *pcolumn,const int n) //row表示当前要查找的点的行数(1~n)
{
static int row=1;//查找点的起始行数为第一行
if (pcolumn[0]==0 && pcolumn[1]==0) //若pcolumn数组被置零,说明重新开始查找,将row的值初始化为1
{
row=1;//
}
int flag=0;//标志变量,值为1表示找到的皇后的点不满足条件
for (int column1=1; column1<=n; column1++) //从row行的第1列开始寻找点,直到该行的最后一列
{
for (int row1=1; row1<row; row1++) //依次与已找到的皇后点比较,若有冲突则flag=1,且continue列数
{
if (pcolumn[row1]==column1 || row1-pcolumn[row1]==row-column1 || row1+pcolumn[row1]==row+column1) //判断该行上的点(row,column1)是否与已有的皇后点处在同一列或同一左斜线或同一右斜线
{
flag=1;
break;
}
}
if (flag==1)
{
flag=0;
continue;
}
pcolumn[row]=column1;//若满足条件,记录该行皇后的列数(纵坐标)
row++;//因为已找到,所以进入下一行
if (row-1==n) //若找齐所有皇后的点
{
pcolumn[0]++;//用pcolumn[0]表示摆法的种数,种数+1
row=row-2;//row回到倒数第2行
return pcolumn[0];
}
else
{
checkPoint(pcolumn,n);//递归算法,在row行开始寻找点
}
}
row--;//若该行所有列数都找完,都找不到满足条件的点,则回到上一行(上一层循环)
return pcolumn[0];//返回当前已找到的所有摆法
}