前几天,突然有朋友要让解决八皇后问题,当时听了真有些刷刷流汗的感觉,因为许久不弄算法了,这是其一,而且当时上大一时对八皇后问题很感兴趣,但当时能力所限,弄了一周也没有求出全解.后来虽然理论知识充分了,但也已经没有时间去研究.
拿着VS一边流汗一边CODE,记着当前说这个东西要用分治和递归来解决,用了半小时,嘿,还真写出来了,呵呵,看来有压力的话还是有些作用的.
贴上来,分享一下:欢迎拍砖:
注:用的是递归+分治
/*
* N皇后问题
* 因为在一张N*N的棋盘上,只放N个棋子,
* 且显然,同一行上,只会放一个(否则就
* 会被同行的吃掉),故用一个N维数组来
* 存储这N个棋子的信息,其中若
* N[i] = j
* 表示在棋盘上第i行第j列放有一个棋子
*/
int count = 0;//用于对结果集的计数
/*输出N皇后问题的解
*输入:
*a[]
*保存棋子信息的数组.
*length
*数组的长度,对应于N
*/
void output (int a[],int length){
int i ,j;
count ++;
printf("The %d of the solution is :/n",count);
for(int i =0;i<length;i++){
for(int j= 0;j<length;j++)
printf("%d",a[i]==j?1:0);
printf("/n");
}
}
/* 往棋盘上放棋子的递归算法
* 输入:
* a
* 存储棋子位置的数组
* length
* 数组的长度
* off
* 要放置第几个棋子,从0开始计数
*/
void check(int a[],int length,int off){
int i = 0; //循环计数器
int value; //要放置的值
/*如果off和长度相等,说明棋子已经全放好了,只要将其输出即可*/
if(off == length){
output(a,length);
return;
}
/* 从0value到length表示依次在棋盘的第off行,第value列上放置棋子*/
for(value = 0;value<length;value++){
/*放置后对已放置的棋子进行校验*/
for(i = 0;i<off;i++)
if(value - a[i] == 0 //value-a[i]=0表示同一列上有两个棋子
||value - a[i]== off - i//value-a[i]= off -i表明同一左斜线上有两个棋子
||value - a[i]== i-off) //value-a[i]= i - off表明同一右斜线上有两个棋子
break;//如果不合条件则跳出循环
if(i == off){//i == off说明校验完毕且棋子放置的位置是正确的
a[off] = value;//将棋子放入
check(a,length,off+1);//继续放下一个
}
}
}