C语言解决八皇后的算法问题
著名数学家高斯(当时说70多种)提出,在8X8的方格棋盘中(64格子),放入八个皇后,保证每个皇后之间都不互相攻击。
国际象棋中,皇后的攻击规则是“米”字形,八个皇后的任意两个,都不能在同一行,不能在同一列,也不能在同一条斜线上。一共有多少种方法?
下图,就是符合的一种情况,只做了两个皇后的辅助线,就不赘述了。
代码及实现过程:
下面展示一些 内联代码片
。
#include<iostream>
using namespace std;
int flag[8]={0,0,0,0,0,0,0,0};// 记录符合情况八个皇后的位置,下标代表行,值代表列。
int g=0;//多少种情况
void prin()//打印每种情况
{
g++;//计数,符合的情况
for(int o=0;o<8;o++)//输出符合摆放的flag记录数组
cout<<flag[o];
cout<<":这是第"<<g<<"种情况:"<<endl;
for(int i=0;i<8;i++)
{
for(int j=0;j<8;j++)
{
if(j==flag[i])//flag数组的下表就是皇后的行,数组的值就是皇后的列。
cout<<"[*]";
else
cout<<"[ ]";
}
cout<<endl;
}
}
int zhi(int a,int b){//取两数之差的绝对值
int sum=a>b?(a-b):(b-a);
return sum;
}
bool lie(int n,int m){//两点的纵坐标是否相等
for(int i=0;i<n;i++)
{
if(flag[i]==m)
return false;
}
return true;
}
bool xie(int n,int m){//两点横与横,纵与纵坐标差的绝对值相等,两点在同一斜线上
for(int i=0;i<n;i++)
{
if(zhi(i,n)==zhi(m,flag[i]))
return false;
}
return true;
}
void get(int n){ //n即代表所放皇后位置的行数,也是当前放的第几个皇后的个数
int m;//m(列)是第n行能放的列
for(m=0;m<8;m++) //列从左到右
{
if(lie(n,m)&&xie(n,m))//和之前已放皇后的列不冲突,斜线不冲突 。行
//每放一个就会递增,get(n+1),行不会重复 (不用管)。
{
flag[n]=m;//把不会冲突的这个皇后的列,放到第n个flag数组的标记中,
//记录下第n个皇后的列。行就是n(不用管)。
if(n<7) //是否放到最后一行,最后一个皇后。
get((n+1));//没有就继续往下放 。
else
prin();//否则,放满八个就输出。
flag[n]=0; //*******精髓所在,当符合要求,最后一个皇后放好后,输出函数执行后,
//最内层的递归完成,就会开始回溯,完成递归放的那个皇后收回来,
//循环继续往下走,完成又一个递归,往复直至所有递归完成。
}
}
}
int main(){
get(0);//调用函数,从第0个开始。
return 0;
}
运行结果: