八皇后问题
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;
}