试探回溯
排列问题的所有可能解,但是不同的是尽可能多的,尽可能早的排除一些解。 试探:从一个最初的选择出发,逐步增加解的长度,直到试探完所有的可能性。 回溯:试探中发现与目标不同,则这条路上接下来所有的解被排除,然后回到上一步,继续试探下一个可能的组合。
八皇后问题详解
问题
在国际象棋中,皇后的势力范围(横,竖,斜),怎样在n*n的棋盘上放置n个皇后,使她们不能相互攻击
思路
先将皇后放置在(0,0)的位置,尝试将皇后分配至每行,试探不同的列,如果发现冲突,则试探下一个列,如果下一行皇后无处可放,则回溯到上一行,然后将此行的皇后后移一列,直到放在第一行上的皇后走完所有的列(即试探完了所有的可能性)
代码实现
struct Queen
{
int x
,y
;
Queen(int xx
=0,int yy
=0):x(xx
),y(yy
){};
bool operator
==(Queen
const& q
)const
{
return (x
==q
.x
)||(y
==q
.y
)||(x
+y
==q
.x
+q
.y
)||(x
-y
==q
.x
-q
.y
);
}
bool operator
!=(Queen
const& q
)const
{
return !(*this==q
);
}
}
void place(int
N)
{
stack
<Queen
> solu
;
Queen
q(0,0);
int nsolu
=0;
while((q
.x
>0)!!(q
.y
<N))
{
if(solu
.size()>=N||q
.y
>=N)
{
q
=solu
.pop();
q
.y
++;
}
else
{
while(N>q
.y
&&solu
.find(q
)>=0)
{
q
.y
++;
}
if(N>q
.y
)
{
solu
.pop(q
);
if(solu
.size()>=N)
nsolu
++;
q
.x
++;q
.y
=0;
}
}
}
}