http://ac.jobdu.com/problem.php?pid=1140
八皇后问题早有耳闻,今日终得一见。其实是典型的回溯算法问题,思路较简单,即挨个下棋子,以判断下一个棋子的位置。然而我这道题做了很久,主要纠结在判断下一个棋子的问题上,我用mark二维数组标记当前哪些位置可以下,哪些位置不能下,以期下一个棋子判断时只需判断自己的mark是真或假,但是这种做法的最大问题在于回溯的时候,很难回到之前的状态,除非用多个mark二维数组构成栈,用以保存上一个状态,这样做起来可能很麻烦。另一个判断的方法就是,在下棋子之前,判断自己位置的纵横对角线位置是否有棋子,这样实现起来就容易一些,因为回溯的时候,只需把自己的mark在变为FALSE。这种做法的代码如下:
#include <stdio.h>
int ans[100][9],it;
bool mark[9][9];
void backtrack(int x)
{
if (x>8)
{
for (int k=1;k<=8;++k)
ans[it+1][k]=ans[it][k];
++it;
return;
}
for (int i=1;i<=8;++i)
{
bool flag=false;
for (int j=1;j<=8;++j)
{
if (mark[j][i]==true) flag=true;
if (i-x+j>=0&&i-x+j<=8&&mark[j][i-x+j]==true)
flag=true;
if (i-j+x>=0&&i-j+x<=8&&mark[j][i-j+x]==true)
flag=true;
if (flag) break;
}
if (flag==false)
{
mark[x][i]=true;
ans[it][x]=i;
backtrack(x+1);
mark[x][i]=false;
}
}
return;
}
int main()
{
it=0;
for (int i=1;i<=8;++i)
for (int j=1;j<=8;++j)
mark[i][j]=false;
int n;
backtrack(1);
scanf("%d",&n);
while (n--)
{
int x;
scanf("%d",&x);
for (int i=1;i<=8;++i)
printf("%d",ans[x-1][i]);
printf("\n");
}
return 0;
}