八皇后问题:国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
分析:八皇后问题是回溯算法的典型案例。我想我们在自己做的过程中,是这样的:
是先从(0,0)这个坐标开始排放皇后,
然后(1,2)这个坐标摆放皇后,
然后(2,4)这个坐标摆放皇后,
然后(3,1)这个坐标摆放皇后,
然后(4,3)这个坐标摆放皇后,
这时,你会发现第六行无法摆皇后,此时开始进行回溯,修改(4,3)为(4,7),但又发现下一行也是不能摆皇后,于是取消(4,7),改(3,1)为(3,6),
然后(4,1)这个坐标摆放皇后,
然后(5,3)这个坐标摆放皇后,
然后(6,5)这个坐标摆放皇后,
这时,发现第八行无法摆放皇后,然后取消(5,3)和(6,5),修改(4,1)为(4,3),发现下一行不行
继续修改...........
直到出现八行每一行都正好可以摆放一枚皇后为止,得出一种方案。
同理,继续下去,就会得到结果
#include<stdio.h>
void fun(int n);
int judge(int m,int n);//定义判断函数
int chess[8][8];//定义棋盘格数8*8,
int sum=0;//定义放置方法总和
int main()
{
fun(0);
printf("%d\n",sum);//sum指的是总方案次数
return 0;
}
void fun(int n)
{
int m;
for(m=0;m<8;m++)
{
if(judge(n,m))
{
chess[n][m]=1;
if(n==7)
sum++;//当n==7时,表明得出了一种方案
else
{
fun(n+1);//进行递归
}
chess[n][m]=0;//不满足时,进行回溯
}
}
}
int judge(int n,int m)
{
int d,x,i,y;
d=m-n;//由左到右的斜线上,其横、纵坐标差相等
x=n+m;//由右到左的斜线上,其横、纵坐标和相等
for(i=0;i<8;i++)
{
if(chess[i][m]==1)//判断该列是否有皇后
{
y=0;
break;
}
if((x-i)>=0&&(x-i)<8)
{
if(chess[i][x-i]==1)
{
y=0;
break;
}
}
if((i+d)>=0&&(i+d)<=7)
{
if(chess[i][i+d]==1)
{
y=0;
break;
}
}
}
if(i==8)
y=1;
return y;
}
同理,这也可将推广到N皇后问题上。