八皇后问题是回溯法的经典应用,对回溯法的学习很有帮助。
八皇后问题:在一个8*8的棋盘上放置8个皇后,使她们互不攻击,每个皇后的攻击范围为同行同列和同对角线,要求找出所有解。
我们先在第一行上放一个皇后,再在第二行的每一列上试放一个皇后,如果第二行上某列的皇后和第一行的皇后不冲突,则可以继续在第三行上试放,如果第二行的皇后和第一行的皇后冲突则退出该栈帧(这里就是回溯法的本质:一旦与题目条件冲突,立即退出该层递归),返回到上一个栈帧,我们需要一个全局变量tot来统计解的个数。
#include<iostream>
using namespace std;
int n,C[10],tot=0;
void search(int cur)
{
int i,j;
if(cur==n) tot++;
else
{
for(i=0;i<n;i++)
{
int ok=1;
C[cur]=i;
for(j=0;j<cur;j++)
if(C[cur]==C[j] || cur-C[cur]==j-C[j] || cur+C[cur]==j+C[j])
{
ok=0;
break;
}
if(ok) search(cur+1);
}
}
}
int main()
{
cin>>n;
search(0);
cout<<tot<<endl;
return 0;
}
在递归中,我们把生成和检查结合起来,从而减小不必要的枚举,这就是回溯法。
回溯法的应用范围很广,只要能把待求解的问题分成不太多的步骤,每个步骤又只有不太多的选择,都可以考虑使用回溯法。