八皇后
今天晚上拿C语言来暴力解决八皇后问题
问题描述
在8X8的西洋棋盘上摆放八个皇后
使其不能互相攻击
皇后攻击方式:横排、纵排、对角线
共有多少种摆法
算法描述
最暴力的方法,一个格子一个格子地试。
由于皇后可直线攻击一整行的敌人,因此一个皇后就得独自占据一整行,只需考虑皇后的所在列即可。
定义一个棋盘数组chess[8]来存储0~7行皇后所在的列数。(抢占王位)
再额外定义三个数组用于已经获得王位的皇后宣布主权。
全局变量
int chess[8]={0,0,0,0,0,0,0,0}; //第n行皇后所占据的列数
bool flag[8]={1,1,1,1,1,1,1,1}; //此列位置是否可用
bool d1[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; //表示上对角线第(行号-列号+7)是否可用
bool d2[15]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; //表示下对角线第(行号+列号)是否可用
int num=1;
八皇后部分代码
void eightQueens(int n){
for(int col=0;col<8;col++){ //每个皇后都有八列可供选择
if(flag[col]&&d1[n-col+7]&&d2[n+col]){ //判断此行这个位置的列和上下对角线是否都可用
//抢占王位
chess[n]=col;
//宣布主权¨
flag[col]=0;
d1[n-col+7]=0;
d2[n+col]=0;
//开始递归
if(n<7){
eightQueens(n+1); //但凡有一个皇后没就位都不能进入下一步
}
else{
print(); //皇后均已就位,打印结果
printf("\n");
}
//由内而外退出递归,同时移交主权
flag[col]=1;
d1[n-col+7]=1;
d2[n+col]=1;
}
}
}
递归层次越深,当前皇后受到其他皇后的限制越多
对角线角标计算方法
横坐标自左向右
纵坐标自上而下
0~7
上对角线(左上右下)
横坐标-纵坐标,同一上对角线数值相同
有负值,因此整体加七可消除负值
下对角线(左下右上)
横坐标加纵坐标,同一下对角线数值相同
输出及主函数
//输出
void print(){
printf("第%d种:\n",num);
for(int i=0;i<8;i++){
for(int j=0;j<8;j++){
if(chess[i]==j){
printf("1");
}
else{
printf("0");
}
}
printf("\n");
}
num++;
}
//主函数
int main(){
int n=0;
eightQueens(n);
return 0;
}