代码改变世界

八皇后问题

2011-08-20 01:07  Daniel Zheng  阅读(424)  评论(0编辑  收藏  举报

八皇后问题是一个国际象棋以为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。

  我们定义这样的一个一维数组,数组的下标表示第i行,数组的值表示第i列,数组大小为8,把数组初始化为从0到7的八个不同值。相当与对01234567做全排列,这样所以的数字自然不再同一行,同一列,即数组下标的值各不相同,数组的值各不相同,且都是取从0到7的不同值。

  现在要解决的就是对角线的问题,如果两个元素处在同一对角线,则有数组下标之差的绝对值等于数组元素值之差的绝对值。即 abs(i-j) == abs(array[i] - array[j])。

  代码如下:

#include <stdio.h>
#include
<stdlib.h>
#include
<math.h>

static int total = 0;
const int QueensNum = 8;

void swap(int * a, int * b)
{
if(a == b)
return;

*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}

int check(int array[], int n)
{
int i, j;
for(i=0;i<n;++i)
{
for(j=i+1;j<n;++j)
if(abs(i-j) == abs(array[i] - array[j]))
return 0;
}
return 1;
}
void permutation(int array[], int index, int n)
{
int i;

if (index == n)
{
if(check(array, n))
{
for(i = 0; i<n; ++i)
{
printf(
"(%d,%d) ",i,array[i]);
}
printf(
"\n");
++total;
}

}
else
{
for (i = index; i < n; i++)
{
swap(
&array[index],&array[i]);
permutation(array, index
+ 1, n);
swap(
&array[index],&array[i]);
}
}
}

void QueensInit(int array[],int n)
{
int i;
for(i = 0; i<n; ++i)
{
array[i]
= i;
}
}
int main(int argc, char **argv)
{

int array[QueensNum];
QueensInit(array, QueensNum);
permutation(array,
0 ,QueensNum);
printf(
"total solution number is %d\n", total);

return 0;

}