题目:在N*N的方格棋盘放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
对于给定的N,求出有多少种合法的放置方法。
同一行,同一列:由题可知,N个皇后只能每行放一个,因此采用n元组x[1:n]表示n后问题的解,其中x[i]表示皇后i放在第i行的第x[i]列。由于不允许将两个皇后放在同一列上,所以x[i]互不相同。
处在与棋盘边框成45角的斜线上:假设存在a(i,x[i]),b(k , x[k])我们可知ab两点在同意对角线即斜率为正负一的情况下应满足
i-k=x[i]-x[k]或 i-k=x[k]-x[i]; 由此可得| i-k | = | x[i]-x[k] |
/*
用n元组x[1:n]表示n后问题的解。x[i]表示皇后i放置在棋盘的第i行的第x[i]列
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int n, x[1000]={0};
long sum;
/*
判断第k个后能不能放在x[k]处
两个皇后不能放在统一斜线上:
若2个皇后放置的位置分别是(i,j)和(k,l),
且 i-j = k -l 或 i+j = k+l,则说明这2个皇后处于同一斜线上。
*/
void OutPut()
{
int i;
for (i = 1; i <= n; ++i)
printf("(%d, %d) ", i, x[i]);
printf("\n");
}
int Place(int k)
{
int j;
for ( j = 1; j < k; ++j)
if (abs(k - j) == abs(x[k] - x[j]) || x[j] == x[k])
return 0;
return 1;
}
void BackTrack1(int t)
{
int i;
//如果t>n说明已经完成一次放置
if (t > n)
{
sum++;
OutPut();
}
else
{
for ( i = 1; i <= n; ++i)
{
x[t] = i;
if (Place(t)) //可以放在i位置处,则继续搜索
BackTrack1(t + 1);
}
}
}
int main()
{
int nn;
printf("请输入皇后的个数nn:");
scanf_s("%d", &nn);
n = nn;
sum = 0;
BackTrack1(1);
printf("%d\n", sum);
return 0;
}