在N*N棋盘上放置着N个皇后,使得她们不能相互攻击,每个皇后的攻击范围是同行同列和同对角线,求出所有解。
皇后不能同行,因此可以逐行考虑每个皇后,使其纵向和斜向不会攻击即可。
/*打印棋盘*/
void print()
{
for(int i=0; i<n; i++)
{
int c = C[i];
for(int i=0; i<c; i++)
printf(". ");
printf("Q");
for(int i=c+1; i<n; i++)
printf(". ");
printf("\n");
}
printf("\n");
}
void search(int cur)
{
if(cur == n)
{
print();
}
else for(int i=0; i<n; i++)
{
int ok = 1;
C[cur] = i;
for(int j=0; j<cur; j++)
{
/*纵向和正负对角线不能相互攻击*/
if(C[cur]==C[j] || cur-C[cur]==j-C[j] || cur+C[cur]==j+C[j])
{
ok = 0;
break;
}
}
if(ok) search(cur+1);
}
}
可以进一步提高效率,利用二维数组vis[3][]直接判断当前位置所在的列和对角线是否已经存在皇后。注意,主对角线y-x可能为负值,则加上n。
void search(int cur)
{
if(cur == n)
{
print();
}
else for(int i=0; i<n; i++)
if(!vis[0][i] && !vis[1][cur+i] && !vis[2][cur-i+n])
//当前点在(cur,i),cur+i为所在副对角线,cur-i+n为主对角线
{
C[cur] = i;
vis[0][i] = vis[1][cur+i] = vis[2][cur-i+n] = 1;
search(cur+1);
vis[0][i] = vis[1][cur+i] = vis[2][cur-i+n] = 0; //取消标记
}
}