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;
}