八皇后问题(回溯法)
//在棋盘上放置八个皇后,使得他们互不攻击,每个皇后的攻击范围
//是同行同列和同对角线要求找出所有的解
void serarch(int cur)//cur是行
{
if(curn)tot++;//递归边界,只要走到这里所有的皇后必然不会冲突
else
{
for(int i=0;i<n;i++)
{
int ok=1;
c[cur]=i;//c[cur]代表的是列,尝试把第cur的皇后放在第i列
for(int j=0;j<cur;j++)//检查是否和前面的皇后冲突
if(c[cur]j||cur-c[cur]j-c[j]||cur+c[cur]j+c[j])
{
ok=0;
break;
}
}
if(ok)search(cur+1);//如果合法则继续递归
}
}
//既然是逐行放置的就不会横向攻击,因此只需要检查纵向和斜向即可;
//cur-c[cur]j-c[j]||cur+c[cur]j+c[j]是来检查
//皇后(cur,c[cur])和(j,c[j])是否在同一条对角线上(画出棋盘图就可明白)
/*
程序效率可以进一步提高:利用二维数组vis[2][]直接判断当前的皇后所在列以及对角线已有
其他的皇后,注意道到主对角线标识y-x可能为负数存取是要加上n;
*/
void search(int cur
{
if(cur==n)tot++;
else
{
for(int i=0;i<n;i++)
if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+n])//利二维数组直接判断
{
c[cur]=i;//如果不用记录数组c则可以省略
vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=1;
search(cur+1);
vis[0][i]=vis[1][cur+i]=vis[2][cur-i+n]=0; //切记!!!!一定要该回来
}
}
}
/*
上面的程序有个及其关键的地方:vis数组的使用,他表示已经放置的皇后占据了
哪些lie 主对角线以及副对角线,一般的,如果在回溯法中修改了辅助的全局变量,则
一定要及时的把它们恢复原状
特别的 若函数有多个出口则在每个出口处修复被修改的值
*/
梦里不知身是客,一晌贪欢。