您的位置:首页 > 产品设计 > UI/UE

八皇后

2015-03-19 22:18 162 查看
八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是19世纪著名的数学家高斯1850年提出:在8×8格的国际象棋上摆放8个皇后,使其不能相互共计,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法?
#include <stdio.h>
#define N 8
int count = 0;                      //答案编号
int queen
;                       //第i(0<=i<N)行的皇后在queen[i]列
int col
;                         //第i列是否可以放queen,可以为1,否则为0
int lu_to_rd[2*N];                  //左上(leftup)至右下(rightdown)的斜线上是否可以放queen,可以为1,否则为0
int ld_to_ru[2*N];                  //左下(leftdown)至右上是否可以放queen,可以为1,否则为0
void printArray();                  //打印答案
int able(int i,int j);              //第i行第j列是否是否可以放queen,可以返回1,否则返回0
void  recursion(int i);             //从第i行开始递归求解
int main(void)
{
int i;
for(i=0;i<N;i++)               //初始化
{
col[i] = 1;
}
for(i=0;i<2*N;i++)
{
lu_to_rd[i] = ld_to_ru[i] = 1;
}
recursion(0);
return 0;
}

void printArray()
{
int i,j;
printf("----------------------------------\n");
printf("count: %d \n",count++);
for(i=0;i<N;i++)
{
for(j=0;j<8;j++)
{
if(queen[i]!=j)
{
printf("_");
}
else
{
printf("Q");                                           //打印queen
}

}

printf("\n");
}
printf("----------------------------------\n");
}

int able(int i,int j)
{
if (col[j] == 1 && lu_to_rd[i+j] == 1 && ld_to_ru[i-j-1+N] == 1)   //假如列方向和两个对角线方向上全都可以放queen,
{                                                                  //就返回1
return 1;
}
return 0;
}

void  recursion(int a)
{
int i;
if(a>=N)                                                    //a >= N 说明已经递归到最后一行,输出答案
{
printArray();

}
else
{
for(i=0;i<N;i++)
{
if(able(a,i))
{
queen[a] = i;                                 //第i列可以放queen
col[i] = 0;                                   //因为第i列已经放了queen,则要设置该列和两个对角线方向上为0
lu_to_rd[a+i] = ld_to_ru[a-i-1+N] = 0;

recursion(a+1);                               //递归到下一行求解

col[i] = 1;                                  //上一层递归结束后要更新第i列的信息
lu_to_rd[a+i] = ld_to_ru[a-i-1+N] = 1 ;
}
}
}
}
关于两条斜线上的问题:
一、判断问题
其实判断两个点在不在同一条斜线上,就是判断这两个点是不是属于同一条直线;
利用坐标的思想(x + y = b || x - y = c #两条斜线的倾斜角为45度或135度);
而第i行第j列很容易转换成坐标;例如queen[1] = 2,queen[2] = 1,易得出这两点在同一条斜线上;
二、数组大小问题
8*8的正方形(0,0)(1,0)(0,1).........
会发现由整数点所连起来的倾角为45度的直线一共有13条,但为了判断的方便,我们把(7,0)(0,7)的点也算上;
这样就一共是15条,写简单点就写成了2*N;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息