首先,我们先看看八皇后这个题目。
高斯八皇后
在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。把每个摆法输出,皇后可以用“1”代替。
通过题目 我们可以了解到问题的关键在于“安放八皇后”“检查工作””输出摆法“,而其中最重要的是检查和安放工作,最简单的是输出摆法。
接下来,我们通过函数来将这个问题分解。
#include<stdio.h>
void show();
int queen(int hang);
int check(int hang,int lie);
int q[8][8];
1.检查
int check(int hang,int lie)
{
if(hang==0) return 1;//如果是第一行就不用进行检查了 因为这是你摆的第一个皇后。
for(int i=0;i<=hang-1;i++)
if(q[i][lie]==1) return 0;//检查这之前所有的列。
for(int i=1;;i++)
{
if(hang-i<0||lie-i<0) break;
if(q[hang-i][lie-i]==1) return 0;//检查上左对角线
}
for(int i=1;;i++)
{
if(hang-i<0||lie+i>7) break;
if(q[hang-i][lie+i]==1) return 0;//检查上右对角线
}//因为我们安放皇后是从上到下 所有不需要对下方进行检查
return 1;//当上面都没问题 就代表检查成功了!
}
2.安放
int queen(int hang)//我们将一行一行地放皇后
{
int lie;
for(lie=0;lie<8;lie++)//开始从第一列慢慢开始放了!
{
if(q[hang][lie]==0) q[hang][lie]=1;//使其为1 代表放皇后
if(hang==7)
show();//到第七行 直接输出
else if(check(hang,lie))
queen(hang+1);//如果检查成功 那么开始下一行
q[hang][lie]=0;//上面的环节没有触发的情况下 说明检查失败 即安放失败 那么就使这个位置回归0
}
}
3.输出
void show()//打印出所需八皇后
{
static k=0;
k=k+1;
printf("NO.%d\n",k);
for(int i=0;i<8;i++)
{
for(int j=0;j<8;j++)
printf("%d",q[i][j]);
printf("\n");
}
}
最后只需把主函数加上就行了
int main()
{
queen(0);
}
这样就简单地打出92种八皇后啦!!!
代码
#include<stdio.h>
int q[8][8];
void show()//打印
{
static int k=0;
k = k + 1;
printf("NO.%d\n", k);
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
printf("%d", q[i][j]);
printf("\n");
}
printf("\n");
}
int check(int hang,int lie)//检查前面是否会出现攻击
{
if (hang==0) return 1;
for (int i = 1;; i++)//检查前面行的所有对角线和列
{
if (hang - i < 0 || lie - i < 0) break;
if (q[hang - i][lie - i] == 1) return 0;
}
for (int i = 1;; i++)
{
if (hang - i < 0 || lie + i > 7) break;
if (q[hang - i][lie + i] == 1) return 0;
}
for (int i = 0; i <= hang - 1; i++)
if (q[i][lie] == 1) return 0;
return 1;
}
void queen(int hang)//从行开始 列作为递归的过程
{
int lie;
for (lie = 0; lie < 8; lie++)
{
q[hang][lie] = 1;//安放queen
if (check(hang,lie))
{
if (hang == 7)
show();
else
queen(hang + 1);//安放下一个
}
q[hang][lie] = 0;//安放失败
}
}
int main()
{
queen(0);
}
输出结果