内容:八皇后问题:在一个8*8格的国际象棋棋盘上,安放八个皇后(任意两个皇后不能在同一行、同一列、同一对角线上),写一个程序求出所有的解。
步骤:
算法分析:
任意两个皇后不能在同一行,将第i个皇后放在第i行后,只需要考虑它与前i-1个皇后处于不同的列和不同的对角线上即可。可采取回溯的算法,从上至下一次在每一行放置皇后,进行搜索,若在某一行的任意一列放置皇后后不能满足要求,则不再向下搜索,而进行回溯,回溯至有其他列可放置皇后的一行,再向下搜索,直到搜索到最后一行,找到可行解,输出结果。
概要设计:
Check()函数 | 判断皇后所放位置是否可行 |
Output()函数 | 输出可行解 |
EightQueen()函数 | 采用递归算法实现在row行放置皇后 |
代码如下:
#include <stdio.h>
#include <stdlib.h>
typedef int bool;
#define true 1
#define false 0
int num=0; //解的数目
char m[8][8]={'*'}; //表示棋盘
bool Check(int row,int column)
{
int i,j;
if(row==1)return true;
for(i=0;i<=row-2;i++) //纵向只能有一枚皇后
{
if(m[i][column-1]=='Q')return false;
}
/*左上至右下只能有一枚皇后*/
i=row-2;
j=i-(row-column);
while(i>=0&&j>=0)
{
if(m[i][j]=='Q')return false;
i--;
j--;
}
/*右上至左下只能有一枚皇后*/
i=row-2;
j=row+column-i-2;
while(i>=0&&j<=7)
{
if(m[i][j]=='Q')return false;
i--;
j++;
}
return true;
}
void Output() //为可行解时,输出结果
{
int i,j;
num ++;
printf("可行解 %d:\n",num);
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
printf("%c",m[i][j]);
}
printf("\n");
}
}
/*采用递归函数实现八皇后回溯算法*/
/*该函数求解当棋盘前row-1行已放置好皇后,在第row行放置皇后*/
void EightQueen(int row)
{
int j;
for(j=0;j<8;j++) //考虑在第row行的各列放置皇后
{
m[row-1][j]='Q'; //在其中一列放置皇后
if(Check(row,j+1)==true) //检查在该列放置皇后是否可行
{
if(row==8)Output(); //若该列放置皇后可行且该列为最后一列,则找到一解
else EightQueen(row+1); //若该列可放置皇后,则向下一行继续搜索、求解
} //取出该列皇后,进行回溯,在其他列放置皇后
m[row-1][j]='*';
}
}
void main()
{
EightQueen(1);
}
运行结果:(由于结果数量太多,不再一一罗列)