n皇后问题!
显然,棋盘的每一行可以并且必须摆放一个皇后,所以可以这样设定第i个皇后放在第i行第x[i]列,用一个一维数组来存放每个皇后的在每行的存放的列数。
回溯法求解n皇后问题:
输入:皇后的个数
输出:n皇后问题的解x[n]
1.初始化解向量x[n]={-1};
2.k=1;
3.while(k>=1)
3.1 把皇后k摆放在下一列的位置,即x[k]++; //因为数组下标是从一开始;
3.2 从x[k]开始依次考察每一列,如果皇后k摆放在x[k]位置不发生冲突,则转步骤3.3;
否则x[k]++试探下一列;
3.3 若n个皇后已全部摆放,则输出一个解;
3.4 若尚有皇后没摆放,则k++,转步骤3摆放下一个皇后;
3.5 若x[k]出界,即列数出界,则回溯x[k]=-1,k--,转步骤3重新摆放皇后k,即上一个皇后;
4. 退出循环,说明皇后问题有无解的情况;
c++代码:
using namespace std;
void queen(int n);
int place(int k);
int main(){
cout<<"输入你要求解的几阶皇后问题:";
int n;
cin>>n;
queen(n);
return 0;
}
int place(int k) //判断皇后k摆放在x[k]列是否冲突的函数
{
for(int i=0;i<k;i++)
{
if(x[i]==x[k]||(abs(k-i)==abs(x[k]-x[i]))) //判断不在一列和是否在一条斜线,即将该皇后与前面每个皇后作比较,看成点(行,列),两点斜率绝对值不为1即可
return 1;
}
return 0;
}
void queen(int n)
{
int s=0;
int k=0;
for(int i=0;i<n;i++)
x[i]=-1;
while(k>=0)
{
x[k]++; //当回溯到前一个皇后时,列数自动加一
while(k<n&&place(k)==1)
x[k]++;
if(x[k]<n&&k==n-1)
{
s=s+1;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++) //用n阶数组来展现皇后摆放的位置
{
if(j==x[i])
a[i][j]=1;
else
a[i][j]=0;
cout<<a[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
if(k<n-1&&x[k]<n)
k++;
else
x[k--]=-1;
}
if(s==0)
cout<<"无解"<<endl;
}
浙公网安备 33010602011771号