#include <iostream>
#include <sstream>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdio>
using namespace std;
string b[93];
int Check(int a[],int n)
{
for(int i=1;i<n;i++)
{
if(abs(a[i]-a[n])==abs(i-n) || a[i]==a[n])//见下面注释
return 0;
}
return 1;
}
void queen()
{
int a[256]={0};
int i=1,j,t=1;i表示当前正在搜索第i行的皇后位置
int n=8;
while(i>0)
{
for(a[i]++;a[i]<=n;a[i]++)
{
if(Check(a,i))//如果第i行的皇后与之前的皇后位置上没有冲突,则break跳出循环
break;
}
if(a[i]<=n)/如果a[i]<=n,即上面的for循环是由“break;”跳出来的,即第i行皇后的位置符合条件
{
if(i==n)找到一组解,输出
{
//printf("第%d种解法:\n",t++);
string em="";
char c[2];
for(j=1;j<=n;j++){
string s="";
stringstream ss;
ss<<a[j];
ss>>s;
em+=s;
}
b[t++] = em;
}
else未找完
{
i++;
a[i]=0;
}
}
else
i--;回溯
}
}
int main()
{
int n,q;
scanf("%d",&n);
queen();
for(int i=0;i<n;i++){
scanf("%d",&q);
cout<<b[q]<<endl;
}
return 1;
}
代码注释:
某一行的皇后a[n]不能和之前的皇后a[i]位置有冲突,约束条件为:a、不在同一列:a[n] != a[i]
b、不在同一行:因为现在是每一行求一个皇后的位置,所以同一行不会有冲突,不需要考虑。
c、不在同一对左角线:a[n]-a[i] != n-i
d、不在同一右对角线:a[n]-a[i] != -(n-i)
条件c和d可以合成:abs(a[n]-a[i]) != abs(n-i)
总结:其实这里用到的就是深度优先搜索的思想,从第一行的皇后一直深入去找第二行、第三行...皇后的位置。其中加上了约束条件Check函数进行“剪枝”。这就是回溯算法的思想:深度优先搜索,遇到不满足的情况就进行回溯。