N皇后问题。 在一个N*N国际象棋盘上,
有N个皇后,每个皇后各占一格:要求
皇后间不会出现互相“攻击”的现象。
即不能有两个皇后处在同一行,同一列
或同一对角线上。问 共有多少种不同的方法。
(N是一个大于等于2并且小于等于100的整数)
思路:可以建立以个一维数组来储存N*N棋盘的行,这样的话,当把一个皇后放入棋盘,再把另一个皇后放入棋盘
讨论其是否满足要求的时候,行冲突的问题就解决了,列冲突的话,只需要看map[i]中是否存在相应的列,做出相应
操作;对于对角线判断,从草稿纸上可知,存在对角线冲突的两个皇后的 行列 之间的差的绝对值是相等的,所以,
判断一个位置上是否可以放置皇后的问题得到解决。
#include "stdio.h"
#include "math.h"
const int N = 100; //最多放置皇后个数
int map[N]; //存放皇后所在的行号
int count = 0; //存放解的个数
void Print(int n) //输出解
{
int i;
count++;
printf("第%d 个解" , count);
for(i=1; i<=n; i++)
printf("(%d,%d)",i,map[i]);
printf("\n");
}
int isPlace(int i, int k) //测试第k列的i行上能否摆放皇后
{
int j;
for(j=1 ; j < k ; j++) //j=1到k-1是已经旋转了皇后的列
{
if((map[j]==i) || (abs(map[j]-i)==abs(j-k)))//第j列皇后是否在i行上。位置(map[j],j)与(i,k)是否同对角线
return 0;
}
return 1;
}
void Queens(int k, int n)
{
int i;
if(k>n)
Print(n); //所有皇后放置结束
else
for(i=1; i<=n; i++) //在第k列上穷举每一个位置
if(isPlace(i, k))//此处进行了图的旋转,判断k列中所有的位置,查看是否有可以放置皇后的位置//
{
map[k] = i;// 若有,则进行记录 map的下标为行 储存元素为列//
Queens(k+1, n); //放置余下的皇后
}
}
void main()
{
int n; //n存放实际皇后个数
printf("皇后问题(n<=100):");
scanf("%d",&n);
if(n>99)
printf("n的值太大,不能求解\n");
else
{
printf("皇后问题求解如下:\n");
Queens(1,n);
}
}