问题描述:
求解皇后问题:在n×n的方格棋盘上,放置n个皇后,要求每个皇后不同行、不同列、不同左右对角线。
要求:(1)皇后的个数n由用户输入,其值不能超过20,输出所有的解。
(2)采用类似于栈求解迷宫问题的方法。
代码:
#include <iostream>
#include <cmath>
using namespace std;
int count=0;
typedef struct
{
int col[21];//存储第i个皇后的列号
int top;
}StType;
bool place(StType st,int i,int j)//判断当前皇后位置是否冲突
{
int k=1;
if(i==1)
return true;
while(k<i)//从第1行到第i-1行
{
if(st.col[k]==j||abs(j-st.col[k])==abs(i-k))
return false;
k++;
}
return true;
}
void queen(int n)//求解皇后问题
{
int i;
bool find;
StType st;
st.top=1;
st.col[st.top]=1;
while(st.top>0)
{
i=st.top;
if(st.top==n)//n个皇后放好,输出
{
cout<<"第"<<++count<<"个解为:";
for(int k=1;k<=st.top;k++)
{
cout<<"("<<k<<","<<st.col[k]<<")";
}
cout<<endl;
}
find=false;
for(int k=1;k<=n;k++)//找下一个皇后的列号
if(place(st,i+1,k))
{
st.top++;
st.col[st.top]=k;
find=true;
break;
}
if(find==false)//当前行找不到皇后的列号,回溯
{
while(st.top>0)
{
if(st.col[st.top]==n)
st.top--;
int k;
for(k=st.col[st.top]+1;k<=n;k++)
{
if(place(st,st.top,k))
{
st.col[st.top]=k;
break;
}
}
if(k>n)
st.top--;
else
break;
}
}
}
}
int main()
{
cout << "皇后问题,输入n(n<=20):" ;
int n;
cin>>n;
if(n>20)
cout<<"超出范围"<<endl;
else
{
queen(n);//执行皇后问题求解函数
}
return 0;
}
运行结果:
总结:
此程序用到了2个方法:
1.bool place(StType st,int i,int j)
//判断当前第i行、第j列的皇后位置是否与i行之前的位置有冲突
2.void queen(int n)
//求解皇后问题。
该方法分为3部分。
- 第一部分:n个皇后均放好后输出;
- 第二部分:找下一个皇后的列号;
- 第三部分:若当前行找不到皇后的位置,执行回溯。若此位置的列号已到n,退栈,找上一行的下一个列号;若找不到,退栈,直到栈空,若找到,退出循环。
这三部分栈不为空时的循环,并且用i标记当前皇后的行号,实现三部分的连接。